Merge sources from S-Core's RSA git (release) 2.0alpha master 2.0_alpha
authorJenkins <taeyoung2.son@samsung.com>
Tue, 18 Sep 2012 04:32:12 +0000 (13:32 +0900)
committerJenkins <taeyoung2.son@samsung.com>
Tue, 18 Sep 2012 04:32:12 +0000 (13:32 +0900)
Change-Id: Idff37fd9910874becdedd228b519aca503ee88c9

75 files changed:
AUTHORS [new file with mode: 0644]
LICENSE [new file with mode: 0644]
README [new file with mode: 0644]
package/build.linux [new file with mode: 0755]
package/pkginfo.manifest [new file with mode: 0644]
package/websimulator-core.install.linux [new file with mode: 0755]
package/websimulator-core.install.windows [new file with mode: 0644]
package/websimulator-core.remove.linux [new file with mode: 0755]
package/websimulator-core.remove.windows [new file with mode: 0644]
sdk-wrt-options.txt [new file with mode: 0644]
simulator.bat [new file with mode: 0755]
simulator.sh [new file with mode: 0755]
web-simulator.ico [new file with mode: 0755]
web-simulator.png [new file with mode: 0755]
web/beep.wav [new file with mode: 0644]
web/browserCheck.html [new file with mode: 0644]
web/cache.manifest [new file with mode: 0644]
web/images/NOTICE [new file with mode: 0644]
web/images/README.md [new file with mode: 0644]
web/images/about_Tizen_Simulator_logo.png [new file with mode: 0644]
web/images/arrow.png [new file with mode: 0644]
web/images/circle.png [new file with mode: 0644]
web/images/closedArrowIcon.png [new file with mode: 0644]
web/images/compass.png [new file with mode: 0644]
web/images/contact-icon.png [new file with mode: 0644]
web/images/dontPanic.png [new file with mode: 0644]
web/images/getstarted.png [new file with mode: 0644]
web/images/infoIcon.png [new file with mode: 0644]
web/images/leftArrowIcon.png [new file with mode: 0644]
web/images/load2.gif [new file with mode: 0644]
web/images/menuDraggerIcon.png [new file with mode: 0644]
web/images/openArrowIcon.png [new file with mode: 0644]
web/images/refreshIcon.png [new file with mode: 0644]
web/images/rightArrowIcon.png [new file with mode: 0644]
web/images/settingsIcon.png [new file with mode: 0644]
web/images/sideCollapseIconLeftSide.png [new file with mode: 0644]
web/images/sideCollapseIconRightSide.png [new file with mode: 0644]
web/images/ui-bg-hashed.png [new file with mode: 0644]
web/index.html [new file with mode: 0644]
web/package.json [new file with mode: 0644]
web/ripple.css [new file with mode: 0644]
web/ripple.html [new file with mode: 0644]
web/ripple.js [new file with mode: 0644]
web/themes/dark/images/device.png [new file with mode: 0644]
web/themes/dark/images/ui-bg_flat_25_222222_40x100.png [new file with mode: 0644]
web/themes/dark/images/ui-bg_flat_30_cccccc_40x100.png [new file with mode: 0644]
web/themes/dark/images/ui-bg_flat_50_1e1e1e_40x100.png [new file with mode: 0644]
web/themes/dark/images/ui-bg_glass_40_ffc73d_1x400.png [new file with mode: 0644]
web/themes/dark/images/ui-bg_highlight-hard_30_5871a3_1x100.png [new file with mode: 0644]
web/themes/dark/images/ui-bg_highlight-soft_0_333333_1x100.png [new file with mode: 0644]
web/themes/dark/images/ui-bg_highlight-soft_10_333333_1x100.png [new file with mode: 0644]
web/themes/dark/images/ui-bg_highlight-soft_20_333333_1x100.png [new file with mode: 0644]
web/themes/dark/images/ui-bg_highlight-soft_50_1e1e1e_1x100.png [new file with mode: 0644]
web/themes/dark/images/ui-icons_222222_256x240.png [new file with mode: 0644]
web/themes/dark/images/ui-icons_5871a3_256x240.png [new file with mode: 0644]
web/themes/dark/images/ui-icons_a83300_256x240.png [new file with mode: 0644]
web/themes/dark/images/ui-icons_cccccc_256x240.png [new file with mode: 0644]
web/themes/dark/images/ui-icons_ffffff_256x240.png [new file with mode: 0644]
web/themes/dark/theme.css [new file with mode: 0644]
web/themes/light/images/device.png [new file with mode: 0644]
web/themes/light/images/ui-anim_basic_16x16.gif [new file with mode: 0644]
web/themes/light/images/ui-bg_flat_0_aaaaaa_40x100.png [new file with mode: 0644]
web/themes/light/images/ui-bg_flat_75_ffffff_40x100.png [new file with mode: 0644]
web/themes/light/images/ui-bg_glass_55_fbf9ee_1x400.png [new file with mode: 0644]
web/themes/light/images/ui-bg_glass_65_ffffff_1x400.png [new file with mode: 0644]
web/themes/light/images/ui-bg_glass_75_dadada_1x400.png [new file with mode: 0644]
web/themes/light/images/ui-bg_glass_75_e6e6e6_1x400.png [new file with mode: 0644]
web/themes/light/images/ui-bg_glass_95_fef1ec_1x400.png [new file with mode: 0644]
web/themes/light/images/ui-bg_highlight-soft_75_cccccc_1x100.png [new file with mode: 0644]
web/themes/light/images/ui-icons_222222_256x240.png [new file with mode: 0644]
web/themes/light/images/ui-icons_2e83ff_256x240.png [new file with mode: 0644]
web/themes/light/images/ui-icons_454545_256x240.png [new file with mode: 0644]
web/themes/light/images/ui-icons_888888_256x240.png [new file with mode: 0644]
web/themes/light/images/ui-icons_cd0a0a_256x240.png [new file with mode: 0644]
web/themes/light/theme.css [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..1ccc2a4
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,17 @@
+<<<<<<< HEAD
+Jason Hu <jia-cheng.hu@intel.com>
+Wenchao Wang <wenchao.wang@intel.com>
+Jacob Chen <jacob.chen@intel.com>
+Ziv Chang <ziv.chang@intel.com>
+Franky Yang <franky.yang@intel.com>
+Yang Yan <yang.a.yan@intel.com>
+Defeng Shen <defeng.shen@intel.com>
+=======
+Jason Hu <jia-cheng.hu@intel.com>\r
+Wenchao Wang <wenchao.wang@intel.com>\r
+Jacob Chen <jacob.chen@intel.com>\r
+Ziv Chang <ziv.chang@intel.com>\r
+Franky Yang <franky.yang@intel.com>\r
+Yang Yan <yang.a.yan@intel.com>\r
+Defeng Shen <defeng.shen@intel.com>\r
+>>>>>>> branch 'release' of ssh://hyeongseok.heo@gerrithost/sdk/tools/web-simulator
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..e5983c4
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,438 @@
+                                Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+-------------------------------------------------------
+Copyright 2011 Research In Motion Limited.
+
+Contributors:
+        Brent Lintner (blintner@rim.com)
+        Dan Silivestru (dsilivestru@rim.com)
+        Gord Tanner (gtanner@rim.com)
+        Nino D'Aversa (ndaversa@rim.com)
+        Nukul Bhasin (nbhasin@rim.com)
+
+-------------------------------------------------------
+--> Kudos to third party awesomeness:
+
+* browser-require *
+
+https://github.com/rsms/browser-require
+
+The MIT License
+http://www.opensource.org/licenses/mit-license.php
+Copyright (c) 2010 Rasmus Andersson http://hunch.se/
+
+-------------------------------------------------------
+* jWorkflow *
+
+http://github.com/tinyhippos/jWorkflow/
+
+The MIT License
+http://www.opensource.org/licenses/mit-license.php
+Copyright (c) 2010 all contributors:
+Gord Tanner
+
+-------------------------------------------------------
+* jXHR.js (JSON-P XHR) *
+ v0.1 (c) Kyle Simpson 
+ MIT License
+
+-------------------------------------------------------
+* UI.Acceleromter Control (panel plugin) *
+
+Licensed under the MIT license:
+  Copyright Train Hack 2010
+  Contributors: Wolfram Kriesing, Dan Silivestru, Brent Lintner
+  http://www.opensource.org/licenses/mit-license.php
+
+-------------------------------------------------------
+* jQuery JavaScript Library *
+
+http://jquery.com/
+
+Copyright 2010, John Resig
+Licensed under MIT
+http://jquery.org/license
+
+Includes Sizzle.js
+http://sizzlejs.com/
+Copyright 2010, The Dojo Foundation
+Released under the MIT, BSD, and GPL Licenses.
+
+-------------------------------------------------------
+* jQuery UI *
+
+Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
+licensed under the MIT (MIT-LICENSE.txt)
+
+http://docs.jquery.com/UI
+
+-------------------------------------------------------
+* jQuery Tooltip plugin *
+
+http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
+http://docs.jquery.com/Plugins/Tooltip
+
+Copyright (c) 2006 - 2008 Jörn Zaefferer
+
+Dual licensed under the MIT and GPL licenses:
+  http://www.opensource.org/licenses/mit-license.php
+  http://www.gnu.org/licenses/gpl.html
+
+-------------------------------------------------------
+* Math.uuid.js (v1.4) *
+
+http://www.broofa.com
+mailto:robert@broofa.com
+
+Copyright (c) 2010 Robert Kieffer
+Dual licensed under the MIT and GPL licenses.
+
+-------------------------------------------------------
+* Wii Opera SDK - 3D Math Class v2.7.22 2008-12-14 *
+(c) 2007-2008 Daniel Gump. All Rights Reserved.                          
+ http://wiioperasdk.com, http://hullbreachonline.com                      
+ hullbreach@hullbreachonline.com                                          
+                                                                          
+* Wii Opera SDK - Drawing Class v2.6.16 2008-12-14 * 
+(c) 2007-2008 Daniel Gump. All Rights Reserved
+http://wiioperasdk.com, http://hullbreachonline.com
+hullbreach@hullbreachonline.com
+
+  Wii is a trademark of Nintendo Co., Ltd.                                
+  Opera is a trademark of Opera, ASA.                                     
+  This software package is not associated with either company             
+  but was created to support users of both.  Its alternative name         
+  when supporting other products is the HULLBREACH SDK.                   
+                                                                          
+  Redistribution and use in source and binary forms, with or without      
+  modification, are permitted provided that the following conditions      
+  are met:                                                                
+    * Redistributions of source code must retain the above copyright      
+      notice, this list of conditions and the following disclaimer.       
+    * Redistributions in binary form must reproduce the above copyright   
+      notice, this list of conditions and the following disclaimer in     
+      the documentation and/or other materials provided with the          
+      distribution.                                                       
+    * Neither the names HULLBREACH ONLINE nor WII OPERA SDK nor the names 
+      of its contributors may be used to endorse or promote products      
+      derived from this software without specific prior written           
+      permission.                                                         
+    * If the explicit purpose of the software is not to support the       
+      Nintendo Wii or the Opera Web browser, then the names of such must  
+      not be used in any derived product. The name shall be the           
+      HULLBREACH SDK with a reference link to http://hullbreachonline.    
+                                                                          
+  THIS SOFTWARE IS PROVIDED BY Daniel Gump ''AS IS'' AND ANY EXPRESS OR   
+  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  
+  DISCLAIMED. IN NO EVENT SHALL Daniel Gump BE LIABLE FOR ANY DIRECT,     
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      
+  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      
+  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     
+  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   
+  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      
+  POSSIBILITY OF SUCH DAMAGE.                                             
+
+-------------------------------------------------------
+  OpenLayers.js -- OpenLayers Map Viewer Library
+
+  Copyright 2005-2010 OpenLayers Contributors, released under the Clear BSD
+  license. Full license text below taken from http://svn.openlayers.org/trunk/openlayers/license.txt
+
+        Copyright 2005-2011 OpenLayers Contributors. All rights reserved. See
+        authors.txt for full list.
+         
+        Redistribution and use in source and binary forms, with or without modification,
+        are permitted provided that the following conditions are met:
+         
+        1. Redistributions of source code must retain the above copyright notice, this
+        list of conditions and the following disclaimer.
+         
+        2. Redistributions in binary form must reproduce the above copyright notice,
+        this list of conditions and the following disclaimer in the documentation and/or
+        other materials provided with the distribution.
+         
+        THIS SOFTWARE IS PROVIDED BY OPENLAYERS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
+        OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+        MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+        SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+        INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+        LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+        PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+        LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+        OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+        ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+         
+        The views and conclusions contained in the software and documentation are those
+        of the authors and should not be interpreted as representing official policies,
+        either expressed or implied, of OpenLayers Contributors.
+
+  Includes compressed code under the following licenses:
+
+  (For uncompressed versions of the code used please see the
+  OpenLayers SVN repository: <http://openlayers.org/>)
+
+-------------------------------------------------------
+  Contains portions of Rico <http://openrico.org/>
+  Copyright 2005 Sabre Airline Solutions  
+  
+  Licensed under the Apache License, Version 2.0 (the "License"); you
+  may not use this file except in compliance with the License. You
+  may obtain a copy of the License at the top of this file or a the following
+  link:
+  
+         http://www.apache.org/licenses/LICENSE-2.0  
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+  implied. See the License for the specific language governing
+  permissions and limitations under the License. 
+
+-------------------------------------------------------
+  Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>
+  Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  http://www.apache.org/licenses/LICENSE-2.0
+
+-------------------------------------------------------
+  Contains portions of Gears <http://code.google.com/apis/gears/>
+
+  Copyright 2007, Google Inc.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+   3. Neither the name of Google Inc. nor the names of its contributors may be
+      used to endorse or promote products derived from this software without
+      specific prior written permission.
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  Sets up google.gears.*, which is *the only* supported way to access Gears.
+
+  Circumvent this file at your own risk!
+  In the future, Gears may automatically define google.gears.* without this
+  file. Gears may use these objects to transparently fix bugs and compatibility
+  issues. Applications that use the code below will continue to work seamlessly
+  when that happens.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..051e4b0
--- /dev/null
+++ b/README
@@ -0,0 +1,25 @@
+# Tizen Web Simulator
+
+Tizen Web Simulator is a lightweight tool for developing mobile web applications. Extending the Google Chrome developer tools, it enables running and debugging web APIs for a variety of mobile platforms. It currently supports the Tizen 1.0 Web API.
+
+## Features
+ * Enables running and debugging modern HTML5 web applications.
+ * Supports simulation of platform APIs via Javascript backend. Currently: Tizen 1.0 Web APIs.
+ * Includes configuration panels for sending the application events and messages to debug features such as Geo Location, Accelerometer, Messaging, and more.
+ * Runs on Google Chrome and supports Web Inspector developer tools.
+
+For more detailed features, please refer to https://developer.tizen.org/help/topic/org.tizen.help.gs/Simulator%20Features.html
+
+## Install Google Chrome
+The Tizen Web Simulator runs on the Google Chrome browser. To use the Tizen Web Simulator, you must first download and install Google Chrome on your development platform: http://www.google.com/chrome/
+
+## Starting the Tizen Web Simulator
+ 1. Unzip it to a known location.
+ 2. Navigate to the web-simulator directory and use the included script (simulator.sh or simulator.bat) to launch Chrome and start the simulator.
+
+## Load your application in the simulator
+Once the simulator is running inside of Chrome, you can open your application by entering the full path to your application's primary content file (such as index.html) in the simulator's (not chrome's) URL bar.
+
+Tizen Web Simulator is based on the Ripple Mobile Emulator.
+Copyright 2012 Intel Corporation. Alli rights reserved.
+https://developer.tizen.org
diff --git a/package/build.linux b/package/build.linux
new file mode 100755 (executable)
index 0000000..84f795c
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/sh -xe
+
+PLATFORM=$TARGET_OS
+TEMPDIR=package/websimulator-core.package.$PLATFORM
+INSTALLED_POS=data/tools/websimulator
+TARGET=${TEMPDIR}/${INSTALLED_POS}
+
+# clean
+clean()
+{
+       echo "=========================================CLEAN=============================================="
+       echo ">> SRCDIR : $SRCDIR"
+
+       rm -rf ${SRCDIR}/*.zip
+       rm -rf ${SRCDIR}/*.tar.gz
+       rm -rf ${TARGET}
+}
+
+# build
+build() 
+{
+       echo "=========================================BUILD=============================================="
+
+    echo ">> make target dir"
+       mkdir -p ${TARGET}
+    echo ">> make target dir ok."
+
+    echo ">> copy source in ${TARGET}"
+    FILE_LIST=`ls`
+    for FILE in ${FILE_LIST}
+    do
+        if [ ! "x${FILE}" = "xpackage" ]
+        then
+            cp -r ${FILE} ${TARGET}
+        fi
+    done
+    echo ">> copy source ok."
+
+    echo ">> remove package directory in ${TARGET}"
+    rm -rf ${TARGET}/package
+    echo ">> remove package directory ok."
+}
+
+# install
+install() 
+{
+    echo "=========================================INSTALL============================================"
+    echo ">> DIBS system is responsible for target zipping operation.DIBS system is responsible for target zipping operation."
+}
+
+[ "$1" = "clean" ] && clean
+[ "$1" = "build" ] && build
+[ "$1" = "install" ] && install
+
+echo "success"
diff --git a/package/pkginfo.manifest b/package/pkginfo.manifest
new file mode 100644 (file)
index 0000000..525baac
--- /dev/null
@@ -0,0 +1,32 @@
+Version:1.0.10
+Maintainer:hyeongseok heo <hyeong-seok.heo@samsung.com>, gyeongseok seo <gyeongseok.seo@samsung.com>, jihoon song <jihoon80.song@samsung.com>, changhyun lee <changhyun1.lee@samsung.com>, bonyong lee <bonyong.lee@samsung.com>
+
+Package:websimulator-core
+OS:ubuntu-32
+Build-host-os:ubuntu-32
+Source:web-simualtor
+Description:Web Simulator Plugin
+
+Package:websimulator-core
+OS:ubuntu-64
+Build-host-os:ubuntu-64
+Source:web-simualtor
+Description:Web Simulator Plugin
+
+Package:websimulator-core
+OS:windows-32
+Build-host-os:ubuntu-32
+Source:web-simualtor
+Description:Web Simulator Plugin
+
+Package:websimulator-core
+OS:windows-64
+Build-host-os:ubuntu-64
+Source:web-simualtor
+Description:Web Simulator Plugin
+
+Package:websimulator-core
+OS:macos-64
+Build-host-os:ubuntu-64
+Source:web-simualtor
+Description:Web Simulator Plugin
diff --git a/package/websimulator-core.install.linux b/package/websimulator-core.install.linux
new file mode 100755 (executable)
index 0000000..ad6029b
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/bash -x
+
+## [ Install Manager's reserved word ]
+## - MENU_DIRECTORY_PATH
+## - MENU_DIRECTORY_NAME
+## - INSTALLED_PATH
+## - USER_DATA_PATH
+## - MAKESHORTCUT_PATH
+
+## User Define for desktop menu
+desktopfile="${HOME}/.local/share/applications/tizen-sdk-websimulator.desktop"
+iconfile="web-simulator.png"
+websimulator_path="${INSTALLED_PATH}/tools/websimulator"
+exefile="simulator.sh"
+comment="The Web Simulator of Tizen SDK"
+name="Web Simulator"
+
+## Do not modify the followings (Make desktop menu)
+exepath="${websimulator_path}/${exefile}"
+icons_path="${websimulator_path}"
+
+chmod 755 ${exepath}
+
+## Register start menu
+if [ -e ${MAKESHORTCUT_PATH} ]
+then
+    ${MAKESHORTCUT_PATH} -f "${desktopfile}" -e "${exepath}" -i "${icons_path}/${iconfile}" -n "${name}" -c "${comment}"
+fi
+
+exit 0
diff --git a/package/websimulator-core.install.windows b/package/websimulator-core.install.windows
new file mode 100644 (file)
index 0000000..a10c63d
--- /dev/null
@@ -0,0 +1,13 @@
+@ECHO OFF
+set shortcut_name=Tizen Web Simulator
+set execute_file=simulator.bat
+set icon_file=web-simulator.ico
+set program_path=%INSTALLED_PATH%\tools\websimulator
+set execute_path=%program_path%\%execute_file%
+set icon_path=%program_path%
+
+echo Setting shortcut...
+wscript.exe "%MAKESHORTCUT_PATH%" /shortcut:"%shortcut_name%" /target:"%execute_path%" /icon:"%icon_path%\%icon_file%"
+
+echo Make shortcut success.
+exit 0
diff --git a/package/websimulator-core.remove.linux b/package/websimulator-core.remove.linux
new file mode 100755 (executable)
index 0000000..d0ad437
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/bash -xe
+## remove shortcut
+DESKTOP_FILE_PATH="${HOME}/.local/share/applications/tizen-sdk-websimulator.desktop"
+${REMOVE_SHORTCUT} ${DESKTOP_FILE_PATH}
+
+## Installer is responsible fo remove websimualtor program. not to here
+### End ###
diff --git a/package/websimulator-core.remove.windows b/package/websimulator-core.remove.windows
new file mode 100644 (file)
index 0000000..f5edc0b
--- /dev/null
@@ -0,0 +1,7 @@
+@echo off
+
+set shortcut_name="Tizen Web Simulator"
+
+:: delims is a TAB followed by a space
+%REMOVE_SHORTCUT% /shortcut:"%shortcut_name%"
+
diff --git a/sdk-wrt-options.txt b/sdk-wrt-options.txt
new file mode 100644 (file)
index 0000000..7e88b2e
--- /dev/null
@@ -0,0 +1 @@
+--allow-file-access-from-files --disable-web-security --start-maximized\r
diff --git a/simulator.bat b/simulator.bat
new file mode 100755 (executable)
index 0000000..6b83e8b
--- /dev/null
@@ -0,0 +1,4 @@
+ver | find "Version 6" && set DIR=%LOCALAPPDATA%|| set DIR=%HOMEDRIVE%%HOMEPATH%\Local Settings\Application Data\r
+set CHROME=%DIR%\Google\Chrome\Application\chrome.exe\r
+set /p OPTIONS= <%CD%\sdk-wrt-options.txt\r
+"%CHROME%" %OPTIONS% --app="file://%CD%/web/index.html" --user-data-dir=%CD%/sdk-profile-data/\r
diff --git a/simulator.sh b/simulator.sh
new file mode 100755 (executable)
index 0000000..0d868d6
--- /dev/null
@@ -0,0 +1,12 @@
+CUR=$(cd $(dirname $0) && pwd)
+CHROME=google-chrome
+if [ "$OS" == "darwin" ] || [ "$(uname)" == "Darwin" ]; then
+    CHROME_PATH=/Applications
+    CHROME="$CHROME_PATH/Google Chrome.app/Contents/MacOS/Google Chrome"
+    if ! test -e "$CHROME"; then
+        CHROME_PATH=~/Desktop
+        CHROME="$CHROME_PATH/Google Chrome.app/Contents/MacOS/Google Chrome"
+    fi
+fi
+
+"$CHROME" $(cat $CUR/sdk-wrt-options.txt) --app=file://$CUR/web/index.html --user-data-dir=./sdk-profile-data/
diff --git a/web-simulator.ico b/web-simulator.ico
new file mode 100755 (executable)
index 0000000..ea883fd
Binary files /dev/null and b/web-simulator.ico differ
diff --git a/web-simulator.png b/web-simulator.png
new file mode 100755 (executable)
index 0000000..7c05129
Binary files /dev/null and b/web-simulator.png differ
diff --git a/web/beep.wav b/web/beep.wav
new file mode 100644 (file)
index 0000000..fef36f0
Binary files /dev/null and b/web/beep.wav differ
diff --git a/web/browserCheck.html b/web/browserCheck.html
new file mode 100644 (file)
index 0000000..195e713
--- /dev/null
@@ -0,0 +1,60 @@
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!DOCTYPE html>
+<html manifest="cache.manifest">
+    <head>
+        <link href="ripple.css" type="text/css" rel="stylesheet" />
+        <script>
+            window.onload = function () {
+                var supportedBrowser, resultWindow, params = {}, url;
+                supportedBrowser = /(Chrome|Chromium)\/(\S+)/;
+                window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(string, key, value) {
+                    params[key] = value;
+                });
+
+                if (params['url'] !== undefined) {
+                    url = "ripple.html?url=" + params['url'];
+                }
+                else {
+                    url = "ripple.html";
+                }
+
+                if (!supportedBrowser.test(navigator.userAgent)) {
+                    resultWindow = document.getElementById("browser-check-result-window");
+                    resultWindow.style.display = "block";
+                    document.getElementById("browserInfo").innerHTML = navigator.userAgent;
+                }
+                else {
+                    document.location.assign(url);
+                }
+            }
+        </script>
+    </head>
+    <body style="background-color: #EFEFEF">
+      <center>
+       <div class="wrong-browser" id="browser-check-result-window"  >
+         <br/><br/>
+          <h2 style="text-align:center">Unsupported Browser</h2>
+         <p><img style="float:left; padding:0px 10px 175px" src="images/dontPanic.png" />Currently only Chrome and Chromium based browsers are 
+           supported by the Web Simulator. </p>
+         <p>You can download Chrome from 
+           <a href="https://www.google.com/chrome">https://www.google.com/chrome</a></p>
+          <p>This browser reported: <span style="color: blue;" id="browserInfo"></span></p>
+
+       </div>
+      </center>
+    </body>
+</html>
diff --git a/web/cache.manifest b/web/cache.manifest
new file mode 100644 (file)
index 0000000..aa12620
--- /dev/null
@@ -0,0 +1,65 @@
+CACHE MANIFEST
+NETWORK:
+*
+CACHE:
+package.json
+images/getstarted.png
+images/leftArrowIcon.png
+images/NOTICE
+images/infoIcon.png
+images/about_Tizen_Simulator_logo.png
+images/load2.gif
+images/closedArrowIcon.png
+images/README.md
+images/contact-icon.png
+images/compass.png
+images/rightArrowIcon.png
+images/menuDraggerIcon.png
+images/ui-bg-hashed.png
+images/refreshIcon.png
+images/openArrowIcon.png
+images/circle.png
+images/settingsIcon.png
+images/sideCollapseIconRightSide.png
+images/arrow.png
+images/dontPanic.png
+images/sideCollapseIconLeftSide.png
+ripple.css
+browserCheck.html
+index.html
+beep.wav
+ripple.js
+ripple.html
+themes/light/images/ui-icons_454545_256x240.png
+themes/light/images/ui-bg_highlight-soft_75_cccccc_1x100.png
+themes/light/images/ui-anim_basic_16x16.gif
+themes/light/images/ui-bg_glass_55_fbf9ee_1x400.png
+themes/light/images/ui-bg_glass_65_ffffff_1x400.png
+themes/light/images/device.png
+themes/light/images/ui-bg_glass_75_e6e6e6_1x400.png
+themes/light/images/ui-bg_glass_95_fef1ec_1x400.png
+themes/light/images/ui-bg_flat_75_ffffff_40x100.png
+themes/light/images/ui-icons_cd0a0a_256x240.png
+themes/light/images/ui-bg_flat_0_aaaaaa_40x100.png
+themes/light/images/ui-icons_222222_256x240.png
+themes/light/images/ui-icons_888888_256x240.png
+themes/light/images/ui-bg_glass_75_dadada_1x400.png
+themes/light/images/ui-icons_2e83ff_256x240.png
+themes/light/theme.css
+themes/dark/images/ui-bg_glass_40_ffc73d_1x400.png
+themes/dark/images/ui-bg_highlight-soft_50_1e1e1e_1x100.png
+themes/dark/images/device.png
+themes/dark/images/ui-bg_highlight-soft_20_333333_1x100.png
+themes/dark/images/ui-icons_a83300_256x240.png
+themes/dark/images/ui-bg_highlight-soft_10_333333_1x100.png
+themes/dark/images/ui-icons_5871a3_256x240.png
+themes/dark/images/ui-icons_cccccc_256x240.png
+themes/dark/images/ui-bg_flat_30_cccccc_40x100.png
+themes/dark/images/ui-icons_222222_256x240.png
+themes/dark/images/ui-bg_flat_50_1e1e1e_40x100.png
+themes/dark/images/ui-icons_ffffff_256x240.png
+themes/dark/images/ui-bg_highlight-soft_0_333333_1x100.png
+themes/dark/images/ui-bg_highlight-hard_30_5871a3_1x100.png
+themes/dark/images/ui-bg_flat_25_222222_40x100.png
+themes/dark/theme.css
+# Manifest build date: Wed Sep 05 2012 10:14:43 GMT+0800 (CST)
\ No newline at end of file
diff --git a/web/images/NOTICE b/web/images/NOTICE
new file mode 100644 (file)
index 0000000..e72aace
--- /dev/null
@@ -0,0 +1,3 @@
+The images and logos provided in this project are proprietary to their \r
+owners, excluded from the Apache 2.0 license, and cannot be used for \r
+any other purpose.\r
diff --git a/web/images/README.md b/web/images/README.md
new file mode 100644 (file)
index 0000000..a80cd64
--- /dev/null
@@ -0,0 +1,4 @@
+# License\r
+\r
+The assets in this directory are excluded from the Apache Software License v.2.0.  Please see the NOTICE file in this directory for more details.\r
+\r
diff --git a/web/images/about_Tizen_Simulator_logo.png b/web/images/about_Tizen_Simulator_logo.png
new file mode 100644 (file)
index 0000000..2c7a186
Binary files /dev/null and b/web/images/about_Tizen_Simulator_logo.png differ
diff --git a/web/images/arrow.png b/web/images/arrow.png
new file mode 100644 (file)
index 0000000..2262e06
Binary files /dev/null and b/web/images/arrow.png differ
diff --git a/web/images/circle.png b/web/images/circle.png
new file mode 100644 (file)
index 0000000..9f204f2
Binary files /dev/null and b/web/images/circle.png differ
diff --git a/web/images/closedArrowIcon.png b/web/images/closedArrowIcon.png
new file mode 100644 (file)
index 0000000..8b08a50
Binary files /dev/null and b/web/images/closedArrowIcon.png differ
diff --git a/web/images/compass.png b/web/images/compass.png
new file mode 100644 (file)
index 0000000..73ca2be
Binary files /dev/null and b/web/images/compass.png differ
diff --git a/web/images/contact-icon.png b/web/images/contact-icon.png
new file mode 100644 (file)
index 0000000..f03c5dd
Binary files /dev/null and b/web/images/contact-icon.png differ
diff --git a/web/images/dontPanic.png b/web/images/dontPanic.png
new file mode 100644 (file)
index 0000000..c1554dd
Binary files /dev/null and b/web/images/dontPanic.png differ
diff --git a/web/images/getstarted.png b/web/images/getstarted.png
new file mode 100644 (file)
index 0000000..ad3db18
Binary files /dev/null and b/web/images/getstarted.png differ
diff --git a/web/images/infoIcon.png b/web/images/infoIcon.png
new file mode 100644 (file)
index 0000000..80c8538
Binary files /dev/null and b/web/images/infoIcon.png differ
diff --git a/web/images/leftArrowIcon.png b/web/images/leftArrowIcon.png
new file mode 100644 (file)
index 0000000..ede74e5
Binary files /dev/null and b/web/images/leftArrowIcon.png differ
diff --git a/web/images/load2.gif b/web/images/load2.gif
new file mode 100644 (file)
index 0000000..3d57da6
Binary files /dev/null and b/web/images/load2.gif differ
diff --git a/web/images/menuDraggerIcon.png b/web/images/menuDraggerIcon.png
new file mode 100644 (file)
index 0000000..9161cea
Binary files /dev/null and b/web/images/menuDraggerIcon.png differ
diff --git a/web/images/openArrowIcon.png b/web/images/openArrowIcon.png
new file mode 100644 (file)
index 0000000..4a6ae6c
Binary files /dev/null and b/web/images/openArrowIcon.png differ
diff --git a/web/images/refreshIcon.png b/web/images/refreshIcon.png
new file mode 100644 (file)
index 0000000..96ae11d
Binary files /dev/null and b/web/images/refreshIcon.png differ
diff --git a/web/images/rightArrowIcon.png b/web/images/rightArrowIcon.png
new file mode 100644 (file)
index 0000000..2242f30
Binary files /dev/null and b/web/images/rightArrowIcon.png differ
diff --git a/web/images/settingsIcon.png b/web/images/settingsIcon.png
new file mode 100644 (file)
index 0000000..6bfc99d
Binary files /dev/null and b/web/images/settingsIcon.png differ
diff --git a/web/images/sideCollapseIconLeftSide.png b/web/images/sideCollapseIconLeftSide.png
new file mode 100644 (file)
index 0000000..c778faa
Binary files /dev/null and b/web/images/sideCollapseIconLeftSide.png differ
diff --git a/web/images/sideCollapseIconRightSide.png b/web/images/sideCollapseIconRightSide.png
new file mode 100644 (file)
index 0000000..89fe750
Binary files /dev/null and b/web/images/sideCollapseIconRightSide.png differ
diff --git a/web/images/ui-bg-hashed.png b/web/images/ui-bg-hashed.png
new file mode 100644 (file)
index 0000000..ee280ba
Binary files /dev/null and b/web/images/ui-bg-hashed.png differ
diff --git a/web/index.html b/web/index.html
new file mode 100644 (file)
index 0000000..195e713
--- /dev/null
@@ -0,0 +1,60 @@
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!DOCTYPE html>
+<html manifest="cache.manifest">
+    <head>
+        <link href="ripple.css" type="text/css" rel="stylesheet" />
+        <script>
+            window.onload = function () {
+                var supportedBrowser, resultWindow, params = {}, url;
+                supportedBrowser = /(Chrome|Chromium)\/(\S+)/;
+                window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(string, key, value) {
+                    params[key] = value;
+                });
+
+                if (params['url'] !== undefined) {
+                    url = "ripple.html?url=" + params['url'];
+                }
+                else {
+                    url = "ripple.html";
+                }
+
+                if (!supportedBrowser.test(navigator.userAgent)) {
+                    resultWindow = document.getElementById("browser-check-result-window");
+                    resultWindow.style.display = "block";
+                    document.getElementById("browserInfo").innerHTML = navigator.userAgent;
+                }
+                else {
+                    document.location.assign(url);
+                }
+            }
+        </script>
+    </head>
+    <body style="background-color: #EFEFEF">
+      <center>
+       <div class="wrong-browser" id="browser-check-result-window"  >
+         <br/><br/>
+          <h2 style="text-align:center">Unsupported Browser</h2>
+         <p><img style="float:left; padding:0px 10px 175px" src="images/dontPanic.png" />Currently only Chrome and Chromium based browsers are 
+           supported by the Web Simulator. </p>
+         <p>You can download Chrome from 
+           <a href="https://www.google.com/chrome">https://www.google.com/chrome</a></p>
+          <p>This browser reported: <span style="color: blue;" id="browserInfo"></span></p>
+
+       </div>
+      </center>
+    </body>
+</html>
diff --git a/web/package.json b/web/package.json
new file mode 100644 (file)
index 0000000..fa4af05
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "name": "ripple",
+  "version": "0.9.2",
+  "description": "A browser based html5 mobile application development and testing tool",
+  "homepage": "http://github.com/blackberry/Rippe-UI",
+  "author": {
+    "name": "Research In Motion",
+    "url": "http://github.com/blackberry/Ripple-UI"
+  },
+  "licenses": [{
+    "type": "Apache 2.0",
+    "url": "http://www.apache.org/licenses/LICENSE-2.0"
+  }],
+  "bin": { "ripple": "./bin/ripple" },
+  "main": "lib/index",
+  "dependencies": {
+    "connect": "1.7.x",
+    "argsparser": "0.0.x",
+    "jsdom": "0.2.4",
+    "jWorkflow": "*"
+  },
+  "bundledDependencies": [
+    "connect",
+    "argsparser"
+  ],
+  "files": [
+    "pkg/web",
+    "node_modules",
+    "README.md",
+    "LICENSE",
+    "lib",
+    "bin"
+  ],
+  "private": true
+}
diff --git a/web/ripple.css b/web/ripple.css
new file mode 100644 (file)
index 0000000..ecfd266
--- /dev/null
@@ -0,0 +1,2264 @@
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* ------------------------------>
+    Global */
+
+html, body {
+    margin: 0 !important;
+    padding: 0 !important;
+    border: 0 !important;
+    width : 100%;
+    height : 100%;
+    overflow-y: auto;
+    overflow-x: hidden;
+}
+
+input, textarea, keygen, select, button, isindex, datagrid {
+    font-size: 1em;
+    margin-left: 0;
+    margin-right: 0;
+    resize: none;
+}
+
+.logo {
+    background-size: 40%;
+    background-repeat: no-repeat;
+    position: absolute;
+    left: 395px;
+    top: 8px;
+    width: 200px;
+    height: 70px;
+}
+
+.beta {
+    -webkit-transform: rotate(-35deg);
+    -moz-transform: rotate(-35deg);
+    -ms-transform: rotate(-35deg);
+    -o-transform: rotate(-35deg);
+    transform: rotate(-35deg);
+    position: absolute;
+    left: 390px;
+    top: 7px;
+}
+
+.main {
+    font-size: 12px !important;
+}
+
+/* TODO: better css for this specificity */
+.main a {
+    text-decoration: underline;
+    outline: none;
+    cursor: pointer;
+}
+
+.main img { border: 0; margin: 0; padding: 0; }
+
+.main table, .main tr, .main td, .main th {
+    border: 0;
+}
+
+.main table{
+    font-size: 1.00em;
+ }
+
+.main select {
+    padding: 0.4em 1em !important;
+}
+
+.main input[type^=text], .main input[type^=number], .main textarea {
+    -webkit-appearance: none;
+    -moz-appearance: none;
+    padding: 0.4em 1em !important;
+}
+
+.main option {
+  background-color: transparent;
+}
+
+input:focus, textarea:focus, isindex:focus, keygen:focus, select:focus {
+    outline: none;
+}
+
+.main input[type^=checkbox] {
+    margin: 6px 10px;
+    padding: 0;
+}
+
+.main label {
+    padding: 0.4em 0.5em 0.4em 0;
+}
+
+.main button:hover, .main select, .main input[type^=submit]:hover, .main input[type^=checkbox]:hover {
+    cursor: pointer;
+}
+
+.h1, .main h1 { font-size: 1.25em; font-weight: bold; }
+
+.h2, .main h2, h3, .main h3 { font-size: 1.07em; font-weight: bold; }
+
+.h4, .main h4 { font-size: 1em; font-weight: normal; }
+
+.irrelevant { display: none; }
+
+section, header, footer, aside, nav { display: block; }
+
+/* ------------------------------>
+    Top Section */
+
+.top-content{
+    margin: 0 auto;
+    position: relative;
+    width: 1px;
+}
+
+.top-content img{
+    position: absolute;
+    top: 0;
+    left: -160px;
+    width: 200px;
+}
+
+.irrelevant {
+    display: none;
+}
+
+/* ------------------------------>
+    Tizen Logo */
+.tizen-logo {
+    margin: 0 auto;
+    top: 35px;
+    position: relative;
+    background-repeat: no-repeat;
+    background-size: 100%;
+    height: 36px;
+    width: 301px;
+}
+
+/* ------------------------------>
+    Middle/Device Wrapper Section */
+
+.middle {
+    margin-left: 0;
+    top: 50px;
+    position: relative;
+}
+
+.viewport-wrapper {
+    -webkit-border-radius: 5px;
+    -moz-border-radius: 5px;
+    border-radius: 5px;
+}
+
+.device-wrapper {
+    position: relative;
+    padding: 28px 28px 45px 28px;
+    -webkit-border-radius: 30px;
+    -moz-border-radius: 30px;
+    border-radius: 30px;
+    margin: 0 42px;
+}
+
+#document {
+    background: white;
+    border: 0 none;
+    width: inherit;
+    height: inherit;
+}
+
+.device-wrapper-landscape {
+    padding: 28px 28px 28px 45px;
+}
+
+/* ------------------------------>
+    Panel (left/right) Section */
+
+section.right, section.left{
+    position: absolute;
+    top: 14px;
+    max-height: 100%;
+    min-height: 26px;
+    padding: 0;
+    width: 344px;
+}
+
+.top {
+    position: absolute;
+    margin: inherit auto inherit auto;
+    top: 0;
+}
+
+section.right { right: 0; }
+
+section.left { 
+    left: 0; 
+    -moz-user-select: none;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    user-select:none;
+}
+
+.sortable > section:not(.ui-box-open):hover {
+    opacity: 0.9;
+}
+
+.ui-box {
+    margin: 0;
+    z-index: 50;
+    position: relative;
+    padding: 0 2px 0 2px;
+}
+
+.ui-box-open {
+    background-image: none !important;
+    padding: 0 2px 2px 2px;
+}
+
+.range-label-right {
+    padding: 4px 0 0 0.75em;
+    float: right;
+    font-weight: bold;
+}
+
+.range-label-left {
+    margin-top: 1px;
+    right: 150px;
+    font-weight: bold;
+    position: absolute;
+}
+
+.info > h3 {
+    margin-bottom: 0.25em;
+}
+
+.panel-label {
+    width: 40%;
+    float: left;
+    position: relative;
+    top: 0.4em;
+}
+
+.panel-bug-textarea {
+    width: 90%;
+}
+
+#info{
+    overflow: auto;
+}
+
+.info{
+    padding: 0.5em 8px 1em 8px;
+    margin: 0;
+    word-wrap: break-word;
+}
+
+.info-header{
+    padding: 0;
+    position: relative;
+    cursor: pointer;    
+}
+
+.info section > span{
+    font-style: normal;
+    font-weight: bold;
+    display: inline;
+    padding-right: 8px;
+}
+
+#preferences-list {
+    overflow: auto ;
+    max-height: 300px;
+}
+
+.preferences-count {
+    float: right;
+    font-size: 1.08em;
+    padding-top: .5em;
+}
+
+.preferences-note{
+    margin-top: .5em;
+    float: right;
+    clear: right;
+}
+
+.preferences-table td {
+    width: 30%;
+    vertical-align: top;
+}
+
+.preferences-table th {
+    text-align: left;
+}
+
+.preferences-table td:nth-child(2), .preferences-table th:nth-child(2) {
+    width: 70%;
+    word-break: break-all;
+}
+
+/* ------------------------------>
+    Panel UI */
+
+.collapse-handle {
+    padding: 5px 9px;
+}
+
+.drag-handle:hover {
+    opacity: 0.75;
+}
+
+.drag-handle:active {
+    opacity: 1.0;
+}
+
+.drag-handle{
+    position: absolute;
+    z-index: 900;
+    right: 7px;
+    top: 4px;
+    opacity: 0.4;
+    cursor: pointer;
+}
+
+.ui-sortable-highlight {
+    height: 26px;
+    margin: 5px;
+    opacity: 0.9;
+}
+
+/* ------------------------------>
+    overlay UI */
+
+.overlay {
+    z-index: 10000;
+    width: 100%;
+    height: 100%;
+    display: none;
+    overflow-y: auto;
+    background-color: white;
+}
+
+.overlay-dialog {
+    z-index: 10001;
+    position: absolute;
+    display: none;
+    -webkit-box-orient: horizontal;
+    -webkit-box-pack: center;
+    -webkit-box-align: center;
+    -moz-box-orient: horizontal;
+    -moz-box-pack: center;
+    -moz-box-align: center;
+    -ms-box-orient: horizontal;
+    -ms-box-pack: center;
+    -ms-box-align: center;
+    overflow-y: auto;
+    background: rgba(0, 0, 0, 0.25);
+}
+
+.overlay-dialog-bottomCenter {
+    -webkit-box-orient: vertical;
+    -webkit-box-pack: end;
+    -moz-box-orient: vertical;
+    -moz-box-pack: end;
+    -ms-box-orient: vertical;
+    -ms-box-pack: end;
+}
+
+.overlay-dialog-topCenter {
+    -webkit-box-orient: vertical;
+    -webkit-box-pack: start;
+    -moz-box-orient: vertical;
+    -moz-box-pack: start;
+    -ms-box-orient: vertical;
+    -ms-box-pack: start;
+}
+
+.overlay-dialog-middleCenter {
+    -webkit-box-orient: vertical;
+    -webkit-box-pack: center;
+    -moz-box-orient: vertical;
+    -moz-box-pack: center;
+    -ms-box-orient: vertical;
+    -ms-box-pack: center;
+}
+
+.overlay-dialog-wrapper-full {
+    height: 100%;
+    width: 100%;
+}
+
+.overlay-dialog-wrapper-large {
+    height: 80%;
+    width: 80%;
+}
+
+.overlay-dialog-wrapper-medium {
+    height: 50%;
+    width: 50%;
+}
+
+.overlay-dialog-wrapper-small {
+    height: 20%;
+    width: 20%;
+}
+
+.overlay-dialog-wrapper-tall {
+    height: 80%;
+}
+
+.overlay-dialog-wrapper {
+    color: #FFF;
+    -webkit-border-radius: 8px;
+    -moz-border-radius: 8px;
+    border-radius: 8px;
+    background: rgba(0,0,0,1.0);
+}
+
+.overlay-dialog-box {
+    padding: 5%;
+    -webkit-border-radius: 8px;
+    -moz-border-radius: 8px;
+    border-radius: 8px;
+    background: rgba(0,0,0,1.0);
+}
+
+.overlay-dialog-title {
+    margin: 0 5px;
+    overflow: hidden;
+    background: rgba(16,16,16,1.0);
+}
+
+.overlay-dialog-message {
+    width: 100%;
+    max-height: 50%;
+    display: block;
+    overflow-y: auto;
+    overflow-x: hidden;
+}
+
+.overlay-dialog-buttons {
+    padding-top: 10px;
+    width:100%;
+    text-align: center;
+}
+
+.overlay-dialog-buttons > input{
+    -webkit-border-radius: 4px;
+    -moz-border-radius: 4px;
+    border-radius: 4px;
+    margin: 5px;
+}
+
+.overlay-menu {
+    z-index: 1000;
+    position: absolute;
+    display: none;
+    overflow-y: auto;
+    background: rgba(0, 0, 0, 0.25);
+}
+
+.overlay-menu-box {
+    position: absolute;
+    bottom: 0;
+    width: 100%;
+    max-height: 80%;
+    max-width: 50%;
+    padding: 3% 0.5% 3% 0.5%;
+    overflow-x: hidden;
+    overflow-y: auto;
+    color: #FFF;
+    -webkit-border-top-right-radius: 8px;
+    border-top-right-radius: 8px;
+    background: rgba(0,0,0,1.0);
+}
+
+.overlay-menu-box::-webkit-scrollbar {  
+    width: 0.50ex;
+    -webkit-border-radius: 1ex;  
+    -moz-border-radius: 1ex;
+    border-radius: 1ex;
+}  
+  
+.overlay-menu-box::-webkit-scrollbar-thumb {  
+    background: #0f55ad;
+    -webkit-border-radius: 1ex;
+    -moz-border-radius: 1ex;
+    border-radius: 1ex;
+}
+
+.overlay-menu-item, .overlay-menu-item-default {
+    width: 100%;
+    display:block;
+    font-size: 1.65em;
+}
+
+.overlay-menu-item:hover, .overlay-menu-item-default:hover {
+    background-color: #0f55ad;
+    cursor: pointer;
+}
+
+.overlay-menu-item-default {
+    background-color: #1F1F1F;
+}
+
+.overlay-menu-buttons > table {
+    color: #FFF;
+}
+
+/* ------------------------------>
+    Notifications */
+
+#panel-notification {
+    position: absolute;
+    width: 40%;
+    min-height: 100px;
+    top: 20%;
+    left: 30%;
+    padding: .5em 1em;
+    font-size: 0.92em;
+    -webkit-box-shadow: 0 1px 10px rgb(0,0,0);
+    -moz-box-shadow: 0 1px 10px rgb(0,0,0);
+    box-shadow: 0 1px 10px rgb(0,0,0);
+    z-index: 1100;
+}
+
+.panel-notification-closebtn {
+    position: relative;
+    float: right;
+    z-index: 999;
+    cursor: pointer;
+    padding: 3px 5px;
+    -webkit-border-radius: 6px;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+}
+
+.panel-notification-closebtn:hover {
+    text-decoration: underline;
+}
+
+#panel-notification-text {
+    word-wrap: break-word;
+}
+
+/* ------------------------------>
+    UI.Devices */
+
+#layout-portrait, #layout-landscape {
+    display: inline-block;
+    width:16px;
+    height:28px;
+    cursor: pointer;
+    padding: 0 10px 0 10px;
+}
+
+#layout-landscape {
+    -webkit-transform: rotate(-90deg);
+    -moz-transform: rotate(-90deg);
+    -o-transform: rotate(-90deg);
+    -ms-transform: rotate(-90deg);
+    transform: rotate(-90deg);
+}
+
+.layout-selected {
+    opacity: 1.0;
+}
+
+.layout-not-selected {
+    opacity: 0.4;
+}
+
+/* ------------------------------>
+    UI.Geo */
+
+#geo-map {
+    position: relative;
+    padding: 10px 0;
+    width: 316px;
+    height: 316px;
+    overflow: hidden;
+}
+
+#geo-map-container {
+    width: 316px;
+    height: 316px;
+    z-index: 0;
+}
+
+#geo-map-img {
+    top: -80px;
+    left: -80px;
+    position: relative;
+}
+
+#geo-map-arrow {
+    width: 32px;
+    height: 32px;
+    background: url(images/compass.png);
+    float: left;
+    margin-top: 5px;
+}
+
+#geo-map-direction-label {
+    margin-left: 35px;
+    z-index: 800;
+}
+
+#geo-map-direction {
+    position: absolute;
+    top: 10px;
+    left: 10px;
+    width: 90px;
+    font-weight: bold;
+    font-size: 1.5em;
+    color: #000;
+    background-color: rgba(180,180,180,0.7);
+    -webkit-border-radius: 5px;
+    -moz-border-radius: 5px;
+    border-radius: 5px;
+    padding: 5px;
+    z-index: 800;
+}
+
+#geo-map-marker {
+    position: absolute;
+    top: 158px;
+    left: 143px;
+    background: url(images/arrow.png);
+    width: 22px;
+    height: 30px;
+    z-index: 800;
+}
+
+.geo-map-zoom-btn {
+    font-weight: bold;
+}
+
+.geo-map-zoom-controls {
+    position: relative;
+    margin-top: 10px;
+}
+
+.geo-map-zoomlevel {
+    position: absolute;
+    right: 0;
+    top: 10px;
+}
+
+
+/* ------------------------------>
+    UI.WidgetConfig */
+
+.ui-accordion-icons .ui-accordion-header a {
+    padding: .25em .5em !important;
+}
+
+#widget-config div > h3:hover {
+    cursor: pointer;
+}
+
+#widget-config h3 a{
+    text-decoration: none !important;
+}
+#widget-config h3 a:hover {
+    text-decoration: none !important;
+}
+
+.configPass, .configFail {
+    height: auto !important;
+}
+
+.configPass:hover, .configFail:hover {
+    opacity: 0.6;
+}
+
+.config-accordion-node-content-value {
+    padding-bottom: .5em;
+}
+
+.config-attributes-name-value {
+    padding-bottom: .5em;
+}
+
+.config-accordion-node-content-attributes-title {
+    padding-bottom: .25em;
+    font-style: italic;
+}
+
+.config-attributes-message {
+    font-style: italic;
+}
+
+.config-accordion-node-content-value-message > span,
+.config-accordion-node-content-value > span,
+.config-accordion-node-content-attributes-title {
+    padding-right: 1em;
+    font-weight: bold;
+}
+
+.config-accordion-node-content-value-message {
+    margin: 0.5em 0;
+}
+
+
+/* ------------------------------>
+    UI.Information Table */
+
+#information-sub-container {
+    line-height: 20px;
+}
+
+.information-widgeticon {
+    float: right;
+    clear: both;
+}
+
+.information-widgetname {
+    font-weight: bold;
+}
+
+#emulator-booting {
+    position: absolute;
+    width: 100%;
+    top: 0;
+    left: 0;
+    height: 100%;
+    z-index: 1200;
+    background: #FFFFFF url("images/load2.gif") center no-repeat;
+}
+
+/* ------------------------------>
+    Panel Table */
+
+.panel-table {
+    width: 100%;
+    border-spacing: 0;
+}
+
+.panel-table th {
+    text-align: left;
+}
+
+.panel-table td input[type^=text], .panel-table td input[type^=number] {
+    width: 100px;
+}
+
+.panel-table td:nth-child(2) {
+    width: 50%;
+    text-align: right;
+}
+
+.panel-table td {
+    vertical-align: middle;
+    height: 30px;
+}
+
+
+/* ------------------------------>
+    UI.Platform */
+
+#device-select {
+    width: 100%;
+    margin: 0.5em 0;
+}
+
+#change-platform {
+    width: 100%;
+    margin: 0.5em 0;
+}
+
+/* ------------------------------>
+    Device Wrapper */
+
+.device-wrapper {
+    background: #1e1e1e;
+    border: solid rgba(204, 204, 204, 0.9);
+    -webkit-box-shadow: 0 0 15px rgba(153, 153, 153, 0.75);
+    -moz-box-shadow: 0 0 15px rgba(153, 153, 153, 0.75);
+    box-shadow: 0 0 15px rgba(153, 153, 153, 0.75);
+}
+
+.viewport-wrapper {
+    background: url(images/ui-bg-hashed.png) repeat;
+    border: 2px solid rgba(204, 204, 204, 0.75);
+}
+/* ------------------------------>
+    Panel collapse icons */
+
+.right-panel-collapse, .left-panel-collapse {
+    position: fixed;
+    top: 0;
+    margin-left: 0;
+    margin-top: 0;
+    opacity: 0.8;
+    cursor: pointer;
+    z-index: 499;
+}
+
+.right-panel-collapse:hover, .left-panel-collapse:hover {
+    opacity: 0.5;
+}
+
+.right-panel-collapse:active, .left-panel-collapse:active {
+    opacity: 1;
+}
+
+.left-panel-collapse {
+    top: 10px;
+    left: 0;
+}
+
+.right-panel-collapse {
+    right: 345px;
+}
+
+#options-menu {
+    font-size: 1.2em;
+    padding: 5px;
+    width: 250px;
+    top: 30px;
+    right: 20px;
+    position: absolute;
+    -moz-box-shadow: 0 0 15px rgba(153, 153, 153, 0.75);
+    -webkit-box-shadow: 0 0 15px rgba(153, 153, 153, 0.75);
+    box-shadow: 0 0 15px rgba(153, 153, 153, 0.75);
+}
+
+#options-menu-build-warning {
+    color: #00CC00;
+    display: none;
+    text-align: center;
+    font-variant:small-caps;
+}
+
+#options-window {
+    width: 100%;
+    height: 100%;    
+    position: absolute;
+    top: 0;
+    display: none;
+    opacity: 0;
+    z-index: 950;
+}
+
+/* ------------------------------>
+    Error Window */
+    
+.error-window {
+    z-index: 10000;
+    width: 100%;
+    height: 100%;    
+    position: absolute;
+    top: 0;
+    text-align:center;
+    vertical-align: middle;    
+    display: none;
+    background-color: #EFEFEF;    
+}
+
+.error-dialog {
+    z-index: 10001;        
+    position: absolute;
+    top: 150px;
+    opacity: 1;
+    width: 500px;
+    height: auto;
+    text-align: center;    
+    vertical-align: middle;
+    margin: 0 auto;    
+    display: none;
+    font-family: Helevetica, Arial;
+}
+
+.error-dialog > button {
+    margin: 0 .25em;
+}
+
+.error-text h2 {
+    font-size: 1.25em;
+}
+
+.error-text p {
+    font-size: 1.17em;
+    text-align: left;
+}
+
+/* ------------------------------>
+    First Run Window */
+.wrong-browser {
+    width: 540px;
+    height: 100%;
+    top: 150px;
+    text-align: left;
+    vertical-align: middle;
+    display: none;
+    margin: 0 auto;
+    font-family: Arial, Verdana, Tahoma, Helevetica, Sans;
+}
+
+.first-run-window {
+    z-index: 9000;
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 0;
+    text-align:center;
+    vertical-align: middle;
+    display: none;
+}
+
+.platform-select-dialog {
+    z-index: 9001;
+    position: absolute;
+    top: 250px;
+    padding: 20px 0 20px 130px;
+    opacity: 1;
+    width: 450px;
+    height: auto;
+    text-align: center;
+    vertical-align: middle;
+    margin: 0 auto;
+    display: none;
+}
+
+.platform-select-logo {
+    position: absolute;
+    width: 122px;
+    height: 200px;
+    top: 0;
+    left: 0;
+}
+
+.platform-select-dialog > button {
+    margin: 0 .25em;
+}
+
+.platform-select-text h2 {
+    font-size: 1.25em;
+}
+
+.platform-select-text p {
+    font-size: 1.17em;
+}
+
+
+/* ------------------------------>
+    Main Scrolling */
+
+::-webkit-scrollbar {
+    width: 0.5em;
+    height: 0.5em;
+    background-color: #bbbbbb;
+    opacity: 0.5;
+}
+
+::-webkit-resizer {
+    -webkit-border-radius: 4px;
+    -moz-border-radius: 4px;
+    border-radius: 4px;
+    background-color: #333333;
+}
+
+::-webkit-scrollbar-thumb {
+    min-height: 0.8em;
+    min-width: 0.8em;
+    margin: 0 .25em;
+    -webkit-border-radius: 4px;
+    -moz-border-radius: 4px;
+    border-radius: 4px;
+    background-color: #aaaaaa;
+}
+
+::-webkit-scrollbar-thumb:hover {
+    background-color: #444444;
+}
+
+::-webkit-scrollbar-thumb:active {
+    background-color: #555555;
+}
+
+/* ------------------------------>
+    Emulator UI Scrolling  */
+
+#document::-webkit-scrollbar {
+    width: 0;
+    height: 0;
+}
+
+#document::-webkit-scrollbar-thumb {
+    min-height: 0;
+    min-width: 0;
+}
+
+/* ------------------------------>
+    Omni Bar */
+
+.omni-bar {
+    position: fixed;
+    width: 100%;
+    min-width:780px;
+    padding: 9px 0 8px 10px;
+    z-index: 999;
+    background-color: rgba(32, 41, 49, 1);
+}
+
+.omni-bar .ui-icon-container {
+    opacity: 1;
+    display: inline-block;
+    top: .3em;
+    position: relative;
+    padding: .3em .3em .1em .3em;
+    cursor: pointer;
+}
+
+.omni-bar .ui-icon-container:hover {
+    opacity: 0.75;
+}
+
+.omni-bar .ui-icon-container:active {
+    opacity: 0.4;
+}
+
+.omni-bar .ui-icon-container-left {
+    margin-left: 0.25em;
+}
+
+.omni-bar .ui-icon-container-right {
+    margin-right: 0.25em;
+}
+
+.omni-bar .ui-icon {
+    display: inline-block;
+}
+
+.omni-bar .options {
+    float: right;
+    margin-right: 16px;
+}
+
+.progress {
+    font-size: 1.5em;
+    font-weight: bold;
+    letter-spacing: 2px;
+    float: right;
+    padding-right: 5px;
+}
+
+.omni-bar input {
+    width: 70%;
+    min-width:150px;
+    height: 15px;
+}
+
+/* ------------------------------>
+    About Dialog */
+.about-logo {
+    background-size: 100%;
+    background-repeat: no-repeat;
+    height: 70px;
+    width: 263px;
+}
+
+/* ------------------------------>
+    fieldset */
+
+fieldset {
+    border-radius: 5px;
+    margin: 5px 0;
+}
+
+.not-ready {
+    opacity: 0.2;
+}
+
+.cap-text {
+    text-transform: capitalize;
+}
+
+/* ------------------------------>
+    jQuery ToolTip Plugin CSS */
+
+#tooltip {
+    position: absolute;
+    z-index: 1001;
+    padding: 0.5em 1em;
+    height: auto;
+    max-width: 400px;
+    word-wrap: break-word;
+    font-size: 12px;
+    cursor: pointer;
+}
+
+#tooltip h3, #tooltip div { margin: 0; }
+
+
+
+/* ------------Tenfour css------------- */
+.stage {
+   height: 100%;
+   background-size: 11px 11px;
+   background-color: rgb(215,217,211);
+   background-image: -webkit-repeating-linear-gradient(left,
+        rgba(128,128,128,.1),
+        transparent 1px,
+        transparent 12px),
+   -webkit-repeating-linear-gradient(top,
+        rgba(128,128,128,.1),
+        transparent 1px,
+        transparent 12px);
+   background-attachment: fixed;
+}
+
+.PanelButtonStyle {
+    font-size:12px;
+    text-align:center;
+    color:#424242;
+    border:1px solid #a1a1a1;
+    line-height:12px;
+    padding:8px 20px 7px 20px;
+    background-color: #fbfbfb;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#ececec)); 
+    background-image: -webkit-linear-gradient(top, #fbfbfb, #ececec); 
+    background-image: -moz-linear-gradient(top, #fbfbfb, #ececec); 
+    background-image: -ms-linear-gradient(top, #fbfbfb, #ececec); 
+    background-image: -o-linear-gradient(top, #fbfbfb, #ececec); 
+    background-image: linear-gradient(to bottom, #fbfbfb, #ececec);
+    -webkit-border-radius: 6px; 
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+    -webkit-background-clip: padding-box;
+    text-decoration:none;
+}
+
+.PanelButtonStyle:hover {
+    color:#55555;
+    background-color: #fbfbfb;
+    border-color:#424242;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#cccccc), to(#777777)); 
+    background-image: -webkit-linear-gradient(top, #cccccc, #777777); 
+}
+
+
+.PanelButtonStyle:active {
+    color:#e0e0e0;
+}
+
+.urlBox {
+    -webkit-border-radius: 5px;
+    -moz-border-radius: 5px;
+    border-radius: 5px;
+    -webkit-box-shadow: inset 0 4px 2px -3px #999;
+    -moz-box-shadow: inset 0 4px 2px -3px #999;
+    box-shadow: inset 0 4px 2px -3px #999;
+    border: none;
+    padding:2px 5px 2px 6px;
+    height:26px;
+    width:300px;
+    color:#a8a8a8;
+    font-size:13px;
+    font-family:sans-serif;
+    font-style:italic;
+}
+
+input.urlBox:focus {
+    color:#424242;
+}
+
+
+.mainButtonContainer {
+    -webkit-border-radius: 6px;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+    min-width:300px;
+    height:26px;
+    padding:3px;
+    background:#252f38;
+    -webkit-box-shadow:  inset 1px 1px 0 0 #1d252c, inset -1px -1px 0 0 #414b53;
+    -moz-box-shadow:  inset 1px 1px 0 0 #1d252c, inset -1px -1px 0 0 #414b53;
+    box-shadow:  inset 1px 1px 0 0 #1d252c, inset -1px -1px 0 0 #414b53;
+    position:relative;}
+
+.button {
+    height:26px;
+    margin:0;
+    padding:5px 10px 7px 10px;
+    text-shadow: -1px -1px 1px #555;
+    position:relative;
+    float:left;
+    color:#cbcbcb;
+    font: 10px Sans-Serif;
+    white-space: nowrap;
+    vertical-align: middle;
+    border:0;
+    -webkit-box-shadow:  inset 1px 1px 0 0 #8a959d, inset -1px -1px 0 0 #262c2f ;
+    -moz-box-shadow:  inset 1px 1px 0 0 #8a959d, inset -1px -1px 0 0 #262c2f ;
+    box-shadow:  inset 1px 1px 0 0 #8a959d, inset -1px -1px 0 0 #262c2f ;
+    background-color: #596674;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#596674), to(#3f4852)); /* Saf4+, Chrome */
+    background-image: -webkit-linear-gradient(top, #596674, #3f4852); /* Chrome 10+, Saf5.1+, iOS 5+ */
+    cursor: pointer;}
+
+.button:hover, .button:focus {
+    -webkit-box-shadow:  inset 1px 1px 0 0 #7999a4, inset -1px -1px 0 0 #1e333b;
+    -moz-box-shadow:  inset 1px 1px 0 0 #7999a4, inset -1px -1px 0 0 #1e333b;
+    box-shadow:  inset 1px 1px 0 0 #7999a4, inset -1px -1px 0 0 #1e333b;
+    background-color: #4a6c7e;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#4a6c7e), to(#324f5c)); /* Saf4+, Chrome */
+    background-image: -webkit-linear-gradient(top, #4a6c7e, #324f5c); /* Chrome 10+, Saf5.1+, iOS 5+ */}
+
+.button:active {
+    -webkit-box-shadow:  inset 2px 0 1px 0 rgba(0,0,0,.4), inset  -2px 0 1px 0 rgba(0,0,0,.4);
+    -moz-box-shadow:  inset 2px 0 1px 0 rgba(0,0,0,.4), inset  -2px 0 1px 0 rgba(0,0,0,.4);
+    box-shadow:  inset 2px 0 1px 0 rgba(0,0,0,.4), inset  -2px 0 1px 0 rgba(0,0,0,.4);
+    padding:6px 9px 6px 11px;
+    background-color: #4a6c7e;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#4a6c7e), to(#324f5c)); /* Saf4+, Chrome */
+    background-image: -webkit-linear-gradient(top, #4a6c7e, #324f5c); /* Chrome 10+, Saf5.1+, iOS 5+ */}
+
+.cornerButton  {
+    -webkit-border-radius: 5px 5px 5px 5px;
+    -moz-border-radius: 5px 5px 5px 5px;
+    border-radius: 5px 5px 5px 5px;
+}
+
+.leftMostButton  {
+    -webkit-border-radius: 5px 0 0 5px;
+    -moz-border-radius: 5px 0 0 5px;
+    border-radius: 5px 0 0 5px;
+}
+
+.rightMostButton {
+    -webkit-border-radius: 0 5px 5px 0;
+    -moz-border-radius: 0 5px 5px 0;
+    border-radius: 0 5px 5px 0;
+}
+
+.leftMostButton.button:active {
+    -webkit-box-shadow: inset -2px 0 1px 0 rgba(0,0,0,.4);
+    -moz-box-shadow: inset -2px 0 1px 0 rgba(0,0,0,.4);
+    box-shadow: inset -2px 0 1px 0 rgba(0,0,0,.4);
+}
+    
+.rightMostButton.button:active {
+    -webkit-box-shadow:  inset 2px 0 1px 0 rgba(0,0,0,.4);
+    -moz-box-shadow:  inset 2px 0 1px 0 rgba(0,0,0,.4);
+    box-shadow:  inset 2px 0 1px 0 rgba(0,0,0,.4);
+}
+    
+.titleBar {
+    border-bottom:1px solid #9b9fa1;
+    position:relative;
+    height:20px;
+    width:320px;
+    background-image: -webkit-linear-gradient(top, #FFFFFF 41%, #E5E5E5 57%);
+    background-image: -webkit-gradient(
+        linear,
+        left top,
+        left bottom,
+        color-stop(0.41, #FFFFFF),
+        color-stop(0.57, #E5E5E5)
+       );
+}
+
+.actualTitle {
+    display:block;
+    font-size:11px;
+    font-family:sans-serif;
+    font-weight:bold;
+    color:#333333;
+    text-transform:uppercase;
+    text-shadow: 1px 1px 1px #fff;
+    white-space: nowrap;
+    padding:4px 0;
+    margin:0 15px 0 20px;
+    height:12px;
+    width:260px;
+    text-decoration:none;
+}
+    
+.closedArrow {
+    background:url(images/closedArrowIcon.png) no-repeat;
+    width:10px;
+    height:10px;
+    display:block;
+    position:absolute;
+    top:6px;
+    left:8px;
+}  
+
+.openArrow {
+    background:url(images/openArrowIcon.png) no-repeat;
+    width:10px;
+    height:10px;
+    display:block;
+    position:absolute;
+    top:7px;
+    left:5px;
+}  
+
+.titleDragger {
+    background:url(images/menuDraggerIcon.png) no-repeat;
+    width:12px;
+    height:8px;
+    display:block;
+    position:absolute;
+    top:7px;
+    right:8px;
+}   
+
+
+.bottomDragBar {
+    border-top:1px solid #9b9fa1;
+    position:relative;
+    height:20px;
+    width:320px;
+    background-image: -webkit-linear-gradient(top, #FFFFFF 21%, #E5E5E5 77%);
+    background-image: -webkit-gradient(
+        linear,
+        left top,
+        left bottom,
+        color-stop(0.21, #FFFFFF),
+        color-stop(0.77, #E5E5E5)
+    );
+}
+
+.bottomCloseIcon {
+    background:url(images/sideCollapseIconLeftSide.png) 7px 6px no-repeat;
+    width:20px;
+    height:20px;
+    display:block;
+    position:absolute;
+    top:0;
+    right:0;
+}
+
+.browsingBtns {
+    padding: 0 0 0 0;
+}
+
+.reloadBtn {
+    margin: 0 0 0 10px;
+}
+
+.PanelCollapseBar {
+    margin-left: 0;
+    top: 0;
+    position:absolute;
+    border-bottom:1px solid #9b9fa1;
+    height:20px;
+    width:346px;
+    background-image: -webkit-linear-gradient(top, #FFFFFF 41%, #E5E5E5 57%);
+    background-image: -webkit-gradient(
+        linear,
+        left top,
+        left bottom,
+        color-stop(0.41, #FFFFFF),
+        color-stop(0.57, #E5E5E5)
+    );
+}
+
+.PanelCollapseBarCollapsed {
+    margin-left: 0;
+    top: 0;
+    position:fixed;
+    padding: 0;
+    height:100%;
+    width:16px;
+    background-color:#fff;
+    border-right: 1px solid #babab9;
+}
+
+#left_div {
+    margin-bottom:20px; 
+    z-index: 0; 
+    padding:0; 
+    background-color: #b7bbbd; 
+    border-right:1px;  
+    width:346px; 
+    height: 100%; 
+    overflow: auto; 
+    overflow-x:hidden; 
+    overflow-y:auto; 
+    position: relative;
+}
+
+#middle_div {
+    position: fixed;
+    left: 347px;
+    top:0;
+    margin:0; 
+    z-index: 0; 
+    padding:0; 
+    width:100%; 
+    height: 100%; 
+    overflow: auto; 
+    overflow-x:hidden; 
+    overflow-y:auto; 
+}
+
+.PanelSectionTitle {
+    font-size: 12px;
+    font-weight: bold;
+    text-transform:uppercase;
+    color: #2c7a94;
+}
+
+select {
+    -webkit-border-radius: 2px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+    -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);
+    -moz-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);
+    box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);
+    border: 1px solid #AAA;
+}
+
+input {
+    border: 1px solid #AAA;
+    -webkit-border-radius: 2px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+    -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);
+    -moz-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);
+    box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);
+}
+
+textarea {
+    border: 1px solid #AAA;
+    -webkit-border-radius: 2px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+    -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);
+    -moz-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);
+    box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);
+}
+
+.tf_panel-table {
+    width: 100%;
+    border-spacing: 6px;
+}
+
+.tf_panel-table th {
+    text-align: left;
+}
+
+.tf_panel-table td input[type^=text], .panel-table td input[type^=number] {
+    width: 100px;
+}
+
+.tf_panel-table td:nth-child(1) {
+    width: 20%;
+    text-align: right;
+}
+
+.tf_panel-table td:nth-child(2) {
+    width: 80%;
+    text-align: left;
+}
+
+.tf_panel-table td {
+    vertical-align: middle;
+    height: 30px;
+}
+
+
+.tf_panel-table2 {
+    width: 100%;
+    border-spacing: 6px;
+}
+
+.tf_panel-table2 th {
+    text-align: left;
+}
+
+.tf_panel-table2 td input[type^=text], .panel-table td input[type^=number] {
+    width: 100px;
+}
+
+.tf_panel-table2 td:nth-child(1) {
+    width: 40%;
+    text-align: right;
+}
+
+.tf_panel-table2 td:nth-child(2) {
+    width: 60%;
+    text-align: left;
+}
+
+.tf_panel-table2 td {
+    vertical-align: middle;
+    height: 30px;
+}
+
+#settings-menu-popup {
+    display: none;
+    width: 306px;
+    padding: 16px 8px 10px 8px;
+    position: absolute;
+    top: 50px;
+    left: 700px;
+    z-index: 900;
+    font-family: Arial, Helvetica, sans-serif;
+    padding-left: 12px;
+    background-color: #f3f3f3;
+    -moz-box-shadow: 0px 10px 15px #555555; /* Firefox 3.6 and earlier */
+    box-shadow: 0px 10px 15px #555555;
+    -webkit-border-radius: 7px 7px 7px 7px;
+    -moz-border-radius: 7px 7px 7px 7px;
+    border-radius: 7px 7px 7px 7px;
+}
+
+#settings-menu-container-div {
+    z-index: 0;
+    padding:0;
+    background-color: #ffffff;
+    border-top:1px solid #a1a1a1;
+    border-left:1px solid #888888;
+    border-right:1px solid #888888;
+    border-bottom:1px solid #888888;
+    width:292px;
+    height:300px;
+    overflow: auto;
+    overflow-x:hidden;
+    overflow-y:auto;
+    position: relative;
+}
+
+.settings-menu-content-table {
+    width: 300px;
+    color: #444444;
+}
+
+.settings-menu-content-table td{
+    font-size: 14px;
+    width:300px;
+    height: 36px;
+    padding-left: 6px;
+    border-bottom:1px solid #a1a1a1;
+    border-style: dotted;
+    -moz-user-select: none;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    user-select:none;
+}
+
+.settings-menu-content-table td:hover{
+    background-color:#FFE680;
+    cursor: pointer
+}
+
+.settings-menu-tab-div{
+    font-size:14px;
+    font-weight:bold;
+    background-color: #c6c6c6;
+    color: #444444;
+    width:160px;
+    height:32px;
+    padding: 0px 0px 0px 0px;
+    text-align:center;
+    vertical-align: middle;
+    display: table-cell;
+    border-top-left-radius:0.7em;
+    border-top-right-radius:0.7em;
+}
+
+.settings-menu-button {
+    color: #444444;
+    font-size: 14px;
+    padding: 5px;
+    width: 70px;
+    font-weight:bold;
+    -moz-border-radius: 5px 5px 5px 5px;
+    -webkit-border-radius: 5px 5px 5px 5px;
+}
+
+.settings-menu-checkbox {
+    width:25px;
+    height:25px;
+    vertical-align: -5px;
+    display: table-cell;
+}
+
+.settings-menu-close-btn {
+    font-size: 12px;
+    width: 24px;
+    height: 20px;
+}
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* ------------------------------>
+    Torch 9860-9850 Skin (602x1149) offset (59x159)*/
+
+.viewport-wrapper-Torch9860-9850 {
+    width: 480px;
+    height: 800px;
+    border: none;
+}
+
+.device-wrapper-Torch9860-9850 {
+    position: relative;
+    padding: 159px 0 0 59px;
+    width: 543px;
+    height: 990px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Torch9860-9850.png') no-repeat;
+}
+
+.menu-button-wrapper-Torch9860-9850 {
+    position: relative;
+    display: inline-block;
+    margin: 40px 0 0 98px;
+    width: 80px;
+    height: 62px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-Torch9860-9850 {
+    position: relative;
+    display: inline-block;
+    margin: 0 0 0 123px;
+    width: 80px;
+    height: 62px;
+    cursor: pointer;
+}
+
+.viewport-wrapper-landscape-Torch9860-9850 {
+    margin: -99px 0 0 103px;
+    width: 800px;
+    height: 480px;
+    border: none;
+}
+
+.device-wrapper-landscape-Torch9860-9850 {
+    position: relative;
+    padding: 159px 0 0 60px;
+    width: 1089px;
+    height: 443px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Torch9860-9850_landscape.png') no-repeat;
+}
+
+.menu-button-wrapper-landscape-Torch9860-9850 {
+    position: relative;
+    margin: -175px 0 0 940px;
+    width: 60px;
+    height: 80px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-landscape-Torch9860-9850 {
+    position: relative;
+    margin: -288px 0 0 940px;
+    width: 60px;
+    height: 80px;
+    cursor: pointer;
+}
+
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* ------------------------------>
+    Bold9900 (726x1258) offset (41x196)*/
+
+.viewport-wrapper-Bold9900 {
+    width: 640px;
+    height: 480px;
+    border: none;
+}
+
+.menu-button-wrapper-Bold9900{
+    position: relative;
+    display: inline-block;
+    margin: 30px 0 0 145px;
+    width: 90px;
+    height: 90px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-Bold9900 {
+    position: relative;
+    display: inline-block;
+    margin: 0 0 0 170px;
+    width: 90px;
+    height: 90px;
+    cursor: pointer;
+}
+
+.device-wrapper-Bold9900 {
+    position: relative;
+    padding: 196px 0 0 41px;
+    width: 685px;
+    height: 1062px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Bold9900.png') no-repeat;
+}
+
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* ------------------------------>
+    Playbook Skin (860x1278) offset (128x130)*/
+
+.viewport-wrapper-landscape-Playbook {
+    height: 600px;
+    width: 1024px;
+    border: none;
+}
+
+.device-wrapper-landscape-Playbook {
+    position: relative;
+    padding: 130px 0 0 127px;
+    height: 732px;
+    width: 1153px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Playbook_landscape.png') no-repeat;
+}
+
+.viewport-wrapper-Playbook {
+    height: 1024px;
+    width: 600px;
+    border: none;
+}
+
+
+.device-wrapper-Playbook {
+    position: relative;
+    padding: 128px 0 0 130px;
+    width: 732px;
+    height: 1153px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Playbook.png') no-repeat;
+}
+
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* ------------------------------>
+    Bold9700 (561x1009) offset (40x181)*/
+
+.viewport-wrapper-Bold9700 {
+    width: 480px;
+    height: 360px;
+    border: none;
+}
+
+.menu-button-wrapper-Bold9700{
+    position: relative;
+    display: inline-block;
+    margin: 30px 0 0 85px;
+    width: 100px;
+    height: 80px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-Bold9700 {
+    position: relative;
+    display: inline-block;
+    margin: 0 0 0 105px;
+    width: 100px;
+    height: 80px;
+    cursor: pointer;
+}
+
+.device-wrapper-Bold9700 {
+    position: relative;
+    padding: 181px 0 0 40px;
+    width: 521px;
+    height: 828px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Bold9700.png') no-repeat;
+}
+
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* ------------------------------>
+    Style9670 (520x1338) offset (78x137)*/
+
+.viewport-wrapper-Style9670 {
+    width: 360px;
+    height: 400px;
+    border: none;
+}
+
+.menu-button-wrapper-Style9670{
+    position: relative;
+    display: inline-block;
+    margin: 210px 0 0 50px;
+    width: 80px;
+    height: 100px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-Style9670 {
+    position: relative;
+    display: inline-block;
+    margin: 0 0 0 100px;
+    width: 80px;
+    height: 100px;
+    cursor: pointer;
+}
+
+.device-wrapper-Style9670 {
+    position: relative;
+    padding: 137px 0 0 80px;
+    width: 440px;
+    height: 1201px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Style9670.png') no-repeat;
+}
+
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* ------------------------------>
+    Curve9350-9360-9370 (560x998) offset (42x172)*/
+
+.viewport-wrapper-Curve9350-9360-9370 {
+    width: 480px;
+    height: 360px;
+    border: none;
+}
+
+.menu-button-wrapper-Curve9350-9360-9370{
+    position: relative;
+    display: inline-block;
+    margin: 30px 0 0 85px;
+    width: 100px;
+    height: 80px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-Curve9350-9360-9370 {
+    position: relative;
+    display: inline-block;
+    margin: 0 0 0 105px;
+    width: 100px;
+    height: 80px;
+    cursor: pointer;
+}
+
+.device-wrapper-Curve9350-9360-9370 {
+    position: relative;
+    padding: 172px 0 0 42px;
+    width: 518px;
+    height: 826px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Curve9350-9360-9370.png') no-repeat;
+}
+
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* ------------------------------>
+    Torch9800 Skin (444x779) offset (40x142)*/
+
+.viewport-wrapper-Torch9800 {
+    width: 360px;
+    height: 480px;
+    border: none;
+}
+
+.device-wrapper-Torch9800 {
+    position: relative;
+    padding: 142px 0 0 40px;
+    width: 404px;
+    height: 637px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Torch9800.png') no-repeat;
+}
+
+.menu-button-wrapper-Torch9800 {
+    position: relative;
+    display: inline-block;
+    margin: 32px 0 0 75px;
+    width: 55px;
+    height: 65px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-Torch9800 {
+    position: relative;
+    display: inline-block;
+    margin: 0 0 0 92px;
+    width: 55px;
+    height: 65px;
+    cursor: pointer;
+}
+
+.viewport-wrapper-landscape-Torch9800 {
+    margin: -99px 0 0 103px;
+    width: 480px;
+    height: 360px;
+    border: none;
+}
+
+.device-wrapper-landscape-Torch9800 {
+    position: relative;
+    padding: 142px 0 0 40px;
+    width: 739px;
+    height: 302px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Torch9800_landscape.png') no-repeat;
+}
+
+.menu-button-wrapper-landscape-Torch9800{
+    position: relative;
+    margin: -137px 0 0 618px;
+    width: 55px;
+    height: 65px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-landscape-Torch9800 {
+    position: relative;
+    margin: -212px 0 0 618px;
+    width: 55px;
+    height: 65px;
+    cursor: pointer;
+}
+
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* ------------------------------>
+    Torch9810 Skin (591x1048) offset (55x191)*/
+
+.viewport-wrapper-Torch9810 {
+    width: 480px;
+    height: 640px;
+    border: none;
+}
+
+.device-wrapper-Torch9810 {
+    position: relative;
+    padding: 191px 0 0 55px;
+    width: 536px;
+    height: 857px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Torch9810.png') no-repeat;
+}
+
+.menu-button-wrapper-Torch9810 {
+    position: relative;
+    display: inline-block;
+    margin: 45px 0 0 100px;
+    width: 75px;
+    height: 85px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-Torch9810 {
+    position: relative;
+    display: inline-block;
+    margin: 0 0 0 118px;
+    width: 75px;
+    height: 85px;
+    cursor: pointer;
+}
+
+.viewport-wrapper-landscape-Torch9810 {
+    width: 640px;
+    height: 480px;
+    border: none;
+}
+
+.device-wrapper-landscape-Torch9810 {
+    position: relative;
+    padding: 55px 0 0 191px;
+    width: 857px;
+    height: 536px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Torch9810_landscape.png') no-repeat;
+}
+
+.menu-button-wrapper-landscape-Torch9810{
+    position: relative;
+    margin: -175px 0 0 685px;
+    width: 85px;
+    height: 75px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-landscape-Torch9810 {
+    position: relative;
+    margin: -272px 0 0 685px;
+    width: 85px;
+    height: 75px;
+    cursor: pointer;
+}
+
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* ------------------------------>
+    Curve9300 (373x674) offset (27x119)*/
+
+.viewport-wrapper-Curve9300 {
+    width: 320px;
+    height: 240px;
+    border: none;
+}
+
+.menu-button-wrapper-Curve9300{
+    position: relative;
+    display: inline-block;
+    margin: 30px 0 0 60px;
+    width: 60px;
+    height: 55px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-Curve9300 {
+    position: relative;
+    display: inline-block;
+    margin: 0 0 0 77px;
+    width: 60px;
+    height: 55px;
+    cursor: pointer;
+}
+
+.device-wrapper-Curve9300 {
+    position: relative;
+    padding: 119px 0 0 27px;
+    width: 346px;
+    height: 555px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Curve9300.png') no-repeat;
+}
+
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* ------------------------------>
+    Pearl9100 (455x969) offset (47x139)*/
+
+.viewport-wrapper-Pearl9100 {
+    width: 360px;
+    height: 400px;
+    border: none;
+}
+
+.menu-button-wrapper-Pearl9100{
+    position: relative;
+    display: inline-block;
+    margin: 30px 0 0 65px;
+    width: 65px;
+    height: 75px;
+    cursor: pointer;
+}
+
+.back-button-wrapper-Pearl9100 {
+    position: relative;
+    display: inline-block;
+    margin: 0 0 0 95px;
+    width: 65px;
+    height: 75px;
+    cursor: pointer;
+}
+
+.device-wrapper-Pearl9100 {
+    position: relative;
+    padding: 139px 0 0 47px;
+    width: 408px;
+    height: 830px;
+    margin: 0 auto;
+    border: none;
+    -webkit-box-shadow: none;
+    -moz-box-shadow: none;
+    box-shadow: none;
+    background: url('images/Pearl9100.png') no-repeat;
+}
+
diff --git a/web/ripple.html b/web/ripple.html
new file mode 100644 (file)
index 0000000..60acba2
--- /dev/null
@@ -0,0 +1,1974 @@
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!DOCTYPE html>
+<html manifest="cache.manifest">
+    <head>
+        <link href="ripple.css" type="text/css" rel="stylesheet" />
+    </head>
+    <title>Web Simulator</title>
+    <body>
+        <section id="ui" class="stage">
+            <section id="emulator-booting"></section>
+            <section id="extension-url" class="irrelevant"></section>
+            <section class="top main">
+                <section class="omni-bar" style="display: none;">
+                    <div class="browsingBtns">
+                        <button id="history-back" class="button leftMostButton"><img src="images/leftArrowIcon.png"></button>
+                        <button id="history-forward" class="button rightMostButton" role="button"><img src="images/rightArrowIcon.png"></button>
+                    </div>
+                    <button id="history-reload" class="button cornerButton" role="button" style="margin-left: 10px;"><img src="images/refreshIcon.png"></button>
+                    <input class="ui-corner-all" type="text" value="" style="margin-left: 18px; min-width:200px;" placeholder="Enter a web application url...">
+                    <span class="options">
+                        <div><button id="options-button-setting-menu" class="button cornerButton" role="button" style="margin-right: 4px;"><img src="images/settingsIcon.png"></button>
+                             <button id="options-button-about" class="button cornerButton" role="button"><img src="images/infoIcon.png"></button>
+                        </div>                        <ul id="options-menu">
+                            <li id="options-menu-build" class="not-ready"><a>Package</a></li>
+                            <li id="options-menu-sign" class="not-ready"><a>Package &amp; Sign</a></li>
+                            <li id="options-menu-launch" class="not-ready"><a>Package &amp; Launch</a></li>
+                            <li id="options-menu-build-warning"><hr>Remote Web Inspector Enabled</li>
+                            <li><hr></li>
+                            <li id="options-menu-settings" class="not-ready"><a>Settings...</a></li>
+                            <li><hr></li>
+                            <li id="options-menu-about"><a>About Simulator</a></li>
+                        </ul>
+                    </span>
+                    <div id="options-progress" class="progress"></div>
+                </section>
+                <section id="setting-menu-overlay">
+                <div id="settings-menu-popup">
+                    <table style="border-collapse: collapse; border-spacing:0px;">
+                        <tr>
+                        <td style="border-width: 0px; padding: 0px;"><div class="settings-menu-tab-div"">Panel Settings</div></td>
+                        <td style="padding-right: 2px; text-align: right; vertical-align: top; display: table-cell;"><button id="settings-menu-close-btn">X</button></td>
+                        </tr>
+                        <tr><td colspan="2" style="background-color: #c6c6c6; padding:4px 4px 4px 4px; height:300px; border-width:0px;">
+                            <div id="settings-menu-container-div">
+                            <table id="settings-menu-content-panel-table" class="settings-menu-content-table">
+                            </table>
+                            </div></td></tr>
+                        <tr><td colspan="2" style="text-align: right; padding:10px 2px 0px 0px;"><button class="settings-menu-button" id="settings-menu-save-btn">Apply</button></td></tr>
+                    </table>
+                </div>
+                <div id="overlayBackground" style="DISPLAY:none; position: absolute; z-index:800; top:0; left:0; background-color:rgba(0, 0, 0, 0.4);"></div>
+                </section>
+            </section>
+            <div class="left-panel-collapse PanelCollapseBar">
+                <img src="images/sideCollapseIconLeftSide.png" style="margin-left:300px; margin-top: 6px;"/>        
+            </div>
+            <div id="left_div">
+            <section id="left" class="left sortable main" style="position: relative;"></section>
+            </div>
+            <div id="middle_div">
+                <section class="middle">
+                    <section id="device-container" class="device-wrapper">
+                        <section id="viewport-container" class="viewport-wrapper">
+                        <section id="overlay-views"><!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="background-window" class="overlay">
+    <h1>The app is currently in the background</h1>
+    <button id="background-return" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+        <span class="ui-button-text">Return to application</span>
+    </button>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="menu-window" class="overlay-menu">
+    <div id="menu-box" class="overlay-menu-box">
+        <div id="menu-buttons" class="overlay-menu-buttons"></div>
+    </div> 
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="dialog-window" class="overlay-dialog">
+    <div id="dialog-wrapper" class="overlay-dialog-wrapper">
+        <div id="dialog-title" class="overlay-dialog-title"></div>
+        <div id="dialog-box" class="overlay-dialog-box">
+            <div id="dialog-message" class="overlay-dialog-message"></div>
+            <div id="dialog-buttons" class="overlay-dialog-buttons"></div>
+        </div>
+    </div>
+</section>
+
+<!--
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="lock-screen-window" class="overlay">
+    <h1>The screen is locked, please unlock it by un-checking "Lock Screen" in the "Device & Network Settings" panel.</h1>
+</section>
+
+</section>
+                     </section>
+                        <div id="menu-button" class="menu-button-wrapper" title="Click to press menu key"></div>
+                        <div id="back-button" class="back-button-wrapper" title="Click to press back key"></div>
+                    </section>
+                </section>
+            </div>
+            <section class="main ui-widget" id="panel-notification" style="display: none;">
+                <section class="panel-notification-closebtn">X</section>
+                <section id="panel-notification-text"></section>
+            </section>
+            <section class="right-panel-collapse ui-state-default ui-corner-all ui-state-hover" style="DISPLAY:none;">
+                <span class="ui-icon ui-icon-arrowthick-1-e"></span>
+            </section>
+            <section class="right sortable main"  style="DISPLAY:none;"></section>
+            <section id="options-window"></section>
+            <section class="error-window"></section>
+            <section class="error-dialog main ui-corner-all">
+                <section class="error-text">
+
+                    <h1>Unsupported Browser</h1>
+                 <p><img style="float:left; padding:0px 10px 75px" src="images/dontPanic.png" />Currently only Chrome and Chromium based browsers are 
+                   supported by the Web Simulator. </p>
+                 <p>You can download Chrome from 
+                   <a href="https://www.google.com/chrome">https://www.google.com/chrome</a></p>
+                    
+                </section>
+            </section>
+
+            <!-- Divs for overlay and platform select dialog -->
+            <div class="first-run-window"></div>
+
+            <section id="panel-views" class="irrelevant"><!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="devices-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Resolution & Orientation</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section class="info ui-widget-content ui-corner-all" style="display: none;">
+        <select id="device-select" class="ui-state-default ui-corner-all"></select>
+        <table class="panel-table">
+            <tr>
+                <td><label class="ui-text-label">Orientation</label></td>
+                <td>
+                    <div id="layout-portrait"></div>
+                    <div id="layout-landscape"></div>
+                </td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">Zooming</label></td>
+                <td>
+                    <label id="screen-zooming-label" class="range-label-left">100%</label>
+                    <input id="screen-zooming" type="range" value="100" min="20" max="150" step="5" class="ui-state-default ui-corner-all">
+            </td>
+            </tr>
+        </table>
+    </section>
+</section>
+
+
+<!--
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="call-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Call</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+    <section id="call" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <section class="call-info">
+            <h3 class="PanelSectionTitle">Local Party</h3>
+            <div id="call-status" style="position:absolute; width:85%; height:120px; z-index:200; padding:10px; background-color:rgba(0, 0, 0, 0.9); color: white; display: none; border-style:solid;
+border-width:3px; border-bottom-width:0px; border-color: gray;"></div>
+            <table id="call-local-dialer" class="tf_panel-table2">
+                <tr>
+                    <td><image src="images/contact-icon.png"></td>
+                    <td><label class="ui-text-label">Simulator Bot</label></td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label">Auto recording</label></td>
+                    <td><input id="recording-status" type="checkbox" class="ui-state-default ui-corner-all"></td>
+                </tr>
+                <tr>
+                    <td>
+                        <button id="call-local-call" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+                            <span id="call-local-text" class="ui-button-text">Call</span>
+                        </button>
+                    </td>
+                    <td><select id="call-local-phone-number" class="ui-state-default ui-corner-all"></select></td>
+                </tr>
+                <tr><td colspan="2">&nbsp;---------------------------------------------------------------------------</td></tr>
+            </table>
+               <h3 class="PanelSectionTitle">Remote Party</h3>
+            <div id="remote-call-status" style="position:absolute; width:85%; height:120px; z-index:200; padding:10px; background-color:rgba(0, 0, 0, 0.9); color: white; display: none; border-style:solid;
+border-width:3px; border-bottom-width:0px; border-color: gray;"></div>
+            <table id="call-remote-dialer" class="tf_panel-table2">
+                <!--
+                <tr>
+                    <td><label class="ui-text-label">Phone Number</label></td>
+                    <td><select id="call-remote-phone-number" class="ui-state-default ui-corner-all"></select></td>
+                </tr>
+                -->
+                <tr>
+                    <td><image src="images/contact-icon.png"></td>
+                    <td><label class="ui-text-label"><span id="remotePartyName"></span></label></td>
+                </tr>
+                <tr>
+                    <td>
+                        <button id="call-remote-call" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+                            <span id="call-remote-text" class="ui-button-text">Call</span>
+                        </button>
+                    </td>
+                    <td>
+                        <label class="ui-text-label" style="font-size:14px;">Simulator Bot</label>
+                    </td>
+                </tr>
+                <tr><td colspan="2">&nbsp;---------------------------------------------------------------------------</td></tr>
+            </table>
+               <h3 class="PanelSectionTitle">End call with</h3>
+            <table id="call-exception" class="tf_panel-table2">
+                <tr>
+                    <td><label class="ui-text-label">Reason</label></td>
+                    <td><select id="call-exception-type" class="ui-state-default ui-corner-all"></select></td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label">End</label></td>
+                    <td><input id="call-exception-status" type="checkbox" class="ui-state-default ui-corner-all"></td>
+                </tr>
+            </table>
+        </section>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="gps-container" class="ui-box ui-state-default">
+    <section class="h2 info-header" style="z-index:900;">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Geolocation</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section class="info ui-widget-content ui-corner-all" style="display: none;">
+        <p></p>
+
+        <table class="panel-table">
+            <tr>
+                <td><label id="label-geo-latitude" class="ui-text-label" for="geo-latitude">Latitude</label></td>
+                <td><input id="geo-latitude" class="ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr>
+                <td><label id="label-geo-longitude" class="ui-text-label" for="geo-longitude">Longitude</label>
+                </td>
+                <td><input id="geo-longitude" class="ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr>
+                <td><label id="label-geo-altitude" class="ui-text-label" for="geo-altitude">Altitude</label></td>
+                <td><input id="geo-altitude" class="ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr id="geo-cellid-container">
+                <td><label id="label-geo-cellid" class="ui-text-label" for="geo-cellid">Cell Id</label></td>
+                <td><input id="geo-cellid" class="ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr>
+                <td><label id="label-geo-accuracy" class="ui-text-label" for="geo-accuracy">Accuracy</label></td>
+                <td><input id="geo-accuracy" class="ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr>
+                <td><label id="label-geo-altitudeaccuracy" class="ui-text-label" for="geo-altitudeaccuracy">Altitude Accuracy</label></td>
+                <td><input id="geo-altitudeaccuracy" class="ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr id="geo-heading-container">
+                <td><label id="label-geo-heading" class="ui-text-label" for="geo-heading">Heading</label></td>
+                <td>
+                    <label id="geo-heading-label" class="range-label-left">N</label>
+                    <input id="geo-heading" type="range" value="0" min="0" max="359.5" step="0.5" class="ui-state-default ui-corner-all">
+                </td>
+            </tr>
+            <tr id="geo-speed-container">
+                <td><label id="label-geo-speed" class="ui-text-label" for="geo-speed">Speed</label></td>
+                <td><input id="geo-speed" class="ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr id="geo-delay-container">
+                <td><span class="ui-text-label">GPS Delay (seconds)</span></td>
+                <td>
+                    <label id="geo-delay-label" class="range-label-left">0</label>
+                    <input id="geo-delay" type="range" value="0" min="0" max="30" class="ui-state-default ui-corner-all">
+                </td>
+            </tr>
+            <tr id="geo-timeout-container">
+                <td>
+                    <span class="ui-text-label">Simulate GPS Timeout</span>
+                </td>
+                <td>
+                    <input id="geo-timeout" type="checkbox" />
+                </td>
+            </tr>
+        </table>
+
+        <div id="geo-map">
+            <div id="geo-map-container"></div>
+            <div id="geo-map-direction">
+                <div id="geo-map-arrow"></div>
+                <div id="geo-map-direction-label"></div>
+            </div>
+        </div>
+
+        <section class="geo-map-zoom-controls">
+            <button id="geo-map-zoom-decrease" class="geo-map-zoom-btn PanelButtonStyle">
+                <span class="ui-button-text">-</span>
+            </button>
+            <button id="geo-map-zoom-increase" class="geo-map-zoom-btn PanelButtonStyle">
+                <span class="ui-button-text">+</span>
+            </button>
+
+            <section class="h3 geo-map-zoomlevel">
+                Zoom Level:&nbsp;
+                <span id="geo-map-zoomlevel-value"></span>
+            </section>
+        </section>
+        <div id="disable_geo_panel" style="DISPLAY:none; position: absolute; z-index:800; top:0; left:0; height: 100%; width:100%; background-color:rgba(0, 0, 0, 0.2);">
+            <div  style="position: absolute; top: 45%; width: 100%">
+                <div style="position: relative; top: -50%; width: 100%">
+                    <div align="center" style="padding: 6px; font-size: 22px; font-weight: bold; color: #666666; background-color:#ffffff;">Network is not available</div>
+                </div>
+            </div>
+        </div>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<section id="nfc-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle">
+            <span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>NFC Adapter
+        </section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png" /></span>
+        </section>
+    </section>
+
+    <section id="nfc" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <table class="panel-table">
+        <tr>
+        <td><label class="ui-text-label">Power</label></td>
+        <td><select id="nfc-power" class="ui-state-default ui-corner-all">
+            <option value="On">On</option>
+            <option value="Off">Off</option>
+            </select>
+        </td>
+        </table>
+
+        <div id="nfc-main-container">
+        <table class="panel-table">
+        </tr>
+        <tr>
+        <td><label class="ui-text-label">Polling</label></td>
+        <td><select id="nfc-polling" class="ui-state-default ui-corner-all">
+            <option value="On">On</option>
+            <option value="Off">Off</option>
+            </select>
+        </td>
+        </tr>
+        </table>
+        <select id="nfc-type" style="width: 50%" class="ui-state-default ui-corner-all">
+            <option value="Tag">NFC Tag</option>
+            <option value="Peer">NFC Peer</option>
+        </select>
+        <div style="border: 1px solid #AAA; padding: 0.4em 1em !important;" class="ui-corner-all">
+            <!-- NFCTag -->
+            <div id="nfc-nfctag">
+                <table class="panel-table">
+                <tr>
+                    <td><label class="ui-text-label">Connection Status</label></td>
+                    <td><span id="nfc-tag-connection">Disconnected</span></td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label">Type</label></td>
+                    <td><select id="nfc-tag-type" class="ui-state-default ui-corner-all">
+                        <option value="GENERIC_TARGET">Generic Target</option>
+                        <option value="ISO14443_A">ISO14443-A</option>
+                        <option value="ISO14443_4A">ISO14443-4A</option>
+                        <option value="ISO14443_3A">ISO14443-3A</option>
+                        <option value="MIFARE_MINI">Mifare Mini</option>
+                        <option value="MIFARE_1K">Mifare 1K</option>
+                        <option value="MIFARE_4K">Mifare 4K</option>
+                        <option value="MIFARE_ULTRA">Mifare Ultra</option>
+                        <option value="MIFARE_DESFIRE">Mifare Desfire</option>
+                        <option value="ISO14443_B">ISO14443-B</option>
+                        <option value="ISO14443_4B">ISO14443-4B</option>
+                        <option value="ISO14443_BPRIME">ISO14443-Bprime</option>
+                        <option value="FELICA">Felica</option>
+                        <option value="JEWEL">Jewel</option>
+                        <option value="ISO15693">ISO15693</option>
+                        <option value="UNKNOWN_TARGET">Unknown Target</option>
+                        </select>
+                        <span id="nfc-tag-type-text" style="display: none;"></span>
+                    </td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label">Support NDEF</label></td>
+                    <td><select id="nfc-tag-NDEF-support" class="ui-state-default ui-corner-all">
+                        <option value="Yes">Yes</option>
+                        <option value="No">No</option>
+                        </select>
+                        <span id="nfc-tag-NDEF-support-text" style="display: none;"></span>
+                    </td>
+                </tr>
+                </table>
+                <div style="border: 1px solid #AAA; padding: 0.4em 1em !important;" class="ui-corner-all">
+                <div id="nfc-tag-ndef-container">
+                <div class="ui-corner-all">
+                    <h3 class="config-accordion-node-title">
+                        <a href="#" class="ui-text-pass">NDEF 1</a>
+                    </h3>
+                    <div>
+                        <div>
+                            <div class="config-accordion-node-content-attributes-title">Record 1</div>
+                            <table class="preferences-table">
+                            <tr>
+                                <td><label class="ui-text-label">TNF</label></td>
+                                <td>Well Known</td>
+                            </tr>
+                                <td><label class="ui-text-label">Type</label></td>
+                                <td>TypeA</td>
+                            </tr>
+                                <td><label class="ui-text-label">ID</label></td>
+                                <td>ID001</td>
+                            </tr>
+                            </tr>
+                                <td><label class="ui-text-label">Payload</label></td>
+                                <td>This is 1st payload</td>
+                            </tr>
+                            </table>
+                        </div>
+                        <br>
+                        <div>
+                            <div class="config-accordion-node-content-attributes-title">Record 2</div>
+                            <table class="preferences-table">
+                            <tr>
+                                <td><label class="ui-text-label">TNF</label></td>
+                                <td>Well Known</td>
+                            </tr>
+                                <td><label class="ui-text-label">Type</label></td>
+                                <td>TypeA</td>
+                            </tr>
+                                <td><label class="ui-text-label">ID</label></td>
+                                <td>ID002</td>
+                            </tr>
+                            </tr>
+                                <td><label class="ui-text-label">Payload</label></td>
+                                <td>This is 2nd payload</td>
+                            </tr>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+                <div class="ui-corner-all">
+                    <h3 class="config-accordion-node-title">
+                        <a href="#" class="ui-text-pass">NDEF 2</a>
+                    </h3>
+                    <div>
+                        <div>
+                            <div class="config-accordion-node-content-attributes-title">Record 1</div>
+                            <table class="preferences-table">
+                            <tr>
+                                <td><label class="ui-text-label">TNF</label></td>
+                                <td>Well Known</td>
+                            </tr>
+                                <td><label class="ui-text-label">Type</label></td>
+                                <td>TypeA</td>
+                            </tr>
+                                <td><label class="ui-text-label">ID</label></td>
+                                <td>ID001</td>
+                            </tr>
+                            </tr>
+                                <td><label class="ui-text-label">Payload</label></td>
+                                <td>This is 1st payload</td>
+                            </tr>
+                            </table>
+                        </div>
+                        <br>
+                        <div>
+                            <div class="config-accordion-node-content-attributes-title">Record 2</div>
+                            <table class="preferences-table">
+                            <tr>
+                                <td><label class="ui-text-label">TNF</label></td>
+                                <td>Well Known</td>
+                            </tr>
+                                <td><label class="ui-text-label">Type</label></td>
+                                <td>TypeA</td>
+                            </tr>
+                                <td><label class="ui-text-label">ID</label></td>
+                                <td>ID002</td>
+                            </tr>
+                            </tr>
+                                <td><label class="ui-text-label">Payload</label></td>
+                                <td>This is 2nd payload</td>
+                            </tr>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+                </div>
+                <div id="nfc-tag-raw-container" style="display: none;">
+                    <table class="preferences-table">
+                    <tr>
+                    <td><label class="ui-text-label">Raw Data</label></td>
+                    </tr>
+                    <tr>
+                    <td><textarea id="nfc-raw-data" class="ui-corner-all" rows="8" style="width: 90%;"></textarea></td>
+                    </tr>
+                    </table>
+                </div>
+                </div>
+            </div>
+            <!-- NFCPeer -->
+            <div id="nfc-nfcpeer" style="display: none;">
+                <table class="panel-table">
+                <tr>
+                    <td><label class="ui-text-label">Connection Status</label></td>
+                    <td><span id="nfc-peer-connection">Disconnected</span></td>
+                </tr>
+                </table>
+                <div class="ui-corner-all">
+                    <h3 class="config-accordion-node-title">
+                        <a href="#" class="ui-text-pass">NDEF</a>
+                    </h3>
+                    <div>
+                        <div>
+                            <div class="config-accordion-node-content-attributes-title">Record 1</div>
+                            <table class="preferences-table">
+                            <tr>
+                                <td><label class="ui-text-label">TNF</label></td>
+                                <td>Well Known</td>
+                            </tr>
+                                <td><label class="ui-text-label">Type</label></td>
+                                <td>TypeA</td>
+                            </tr>
+                                <td><label class="ui-text-label">ID</label></td>
+                                <td>ID001</td>
+                            </tr>
+                            </tr>
+                                <td><label class="ui-text-label">Payload</label></td>
+                                <td>This is 1st payload</td>
+                            </tr>
+                            </table>
+                        </div>
+                        <br>
+                        <div>
+                            <div class="config-accordion-node-content-attributes-title">Record 2</div>
+                            <table class="preferences-table">
+                            <tr>
+                                <td><label class="ui-text-label">TNF</label></td>
+                                <td>Well Known</td>
+                            </tr>
+                                <td><label class="ui-text-label">Type</label></td>
+                                <td>TypeA</td>
+                            </tr>
+                                <td><label class="ui-text-label">ID</label></td>
+                                <td>ID002</td>
+                            </tr>
+                            </tr>
+                                <td><label class="ui-text-label">Payload</label></td>
+                                <td>This is 2nd payload</td>
+                            </tr>
+                            </table>
+                        </div>
+                <div align="center">
+                    <span id="nfc-peer-send-msg" style="color: #AA5500; font-size:120%">&nbsp;</span>
+                </div>
+                <div>
+                    <button class="PanelButtonStyle" id="nfc-peer-send" style="width: 100%;"><span class="ui-button-text">Send</span></button>
+                </div>
+                    </div>
+                </div>
+            </div>
+        <br>
+        <div>
+            <table id="nfc-output-table" class="preferences-table" style="display: none;">
+            <tr>
+            <td><label class="ui-text-label">Receive Data</label></td>
+            </tr>
+            <tr>
+            <td><textarea id="nfc-output" class="ui-corner-all" rows="4" style="width: 92%" readonly></textarea></td>
+            </tr>
+            </table>
+        </div>
+        <div align="center">
+            <span id="nfc-attach-msg" style="color: #AA5500; font-size:120%">&nbsp;</span>
+        </div>
+        <div>
+            <button class="PanelButtonStyle" id="nfc-attach" style="width: 100%;"><span class="ui-button-text">Attach</span></button>
+        </div>
+        </div>
+        </section>
+    </div>
+</section>
+    
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<section id="bluetooth-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Bluetooth</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section id="bluetooth" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <section class="bluetooth-info">
+            <span class="PanelSectionTitle">Sending</span>
+            <table class="tf_panel-table">
+                <tr>
+                    <td nowrap><label class="ui-text-label" for="bluetooth-away">Is Away</label></td>
+                    <td><input type="checkbox" name="away" id="bluetooth-away"/></td>
+                </tr>
+                <tr>
+                    <td nowrap><label class="ui-text-label" for="checkboxRFCOMM">Register RFCOMM</label></td>
+                    <td><input type="checkbox" name="checkboxRFCOMM" id="checkboxRFCOMM"/></td>
+                </tr>
+            </table>
+            <span id="bondPrompt" class="PanelSectionTitle" style="color:red;display:none;">Bond Successfully</span>
+            <table class="tf_panel-table">
+                <tr>
+                    <td colspan='2' width="100%" style="text-align:left;">
+                        <div id="operation-bonding" style="display: none;text-size:12px;">
+                            <label class="ui-text-label">Service 1:<span></span>chat</label><br><br>
+                            <label class="ui-text-label">5bce9431-6d25-32ab-afe0-2ecdra30860</label><br><br>
+                            <label id="bluetooth-operation-label" class="ui-text-label">Operation</label><br><br>
+                            <button id="accept-bonding" class="PanelButtonStyle">Accept</button>
+                            <button id="cancel-bonding" class="PanelButtonStyle">Cancel</button>
+                            <br>
+                        </div>
+                    </td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label">Text</label></td>
+                    <td><textarea class="ui-corner-all" id="bluetooth-text" rows="3" style="width: 90%;"></textarea></td>
+                </tr>
+                <tr>
+                    <td colspan='2'>
+                        <button id="bluetooth-send" class="PanelButtonStyle">Send</button>
+                    </td>
+                </tr>
+            </table>
+            <br>
+            <span class="PanelSectionTitle">Receiving</span>
+            <table class="tf_panel-table">
+                <tr>
+                    <td><label class="ui-text-label">Data</label></td>
+                    <td><label class="ui-text-label"><textarea class="ui-corner-all" id="received-data" rows="3" style="width: 90%;" readonly></textarea></label></td>
+                </tr>
+                <tr>
+                    <td colspan='2'><button class="PanelButtonStyle" id="bluetooth-clear">Clear</button></td>
+                </tr>
+            </table>
+        </section>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<section id="touchEvent-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Touch Event</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section id="touchEvent-content" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <div style="text-align:center;position:relative">
+            <canvas id="touch_canvas" width="180px" height="200px" style="border:1px solid #c3c3c3;">
+                No Supptort canvas Label.
+            </canvas>
+            <div>
+                <table class="panel-table">
+                    <tr>
+                        <td>
+                            <label class="ui-text-label">&nbsp;Alt Key</label>
+                            <input id="touch_altKey" type="checkbox" />
+                        </td>
+                        <td>
+                            <label class="ui-text-label">Meta Key</label>
+                            <input id="touch_metaKey" type="checkbox" />
+                        </td>
+                    </tr>
+                    <tr>
+                        <td>
+                            <label class="ui-text-label">Ctrl Key</label>
+                            <input id="touch_ctrlKey" type="checkbox" />
+                        </td>
+                        <td>
+                            <label class="ui-text-label">Shift Key</label>
+                            <input id="touch_shiftKey" type="checkbox" />
+                        </td>
+                    </tr>
+                </table>
+            </div>
+            <input type="button" value="Touch Start" id="touch_option" class="PanelButtonStyle">
+        </div>
+    </section>
+</section>
+
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+<section id="sensors-panel-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Sensors</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section id="sensorsettings-content-container" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <p>Configure sensors information, settings, and events for the current platform.</p>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="platforms-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Platform API</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section class="info ui-widget-content ui-corner-all" style="display: none;">
+        <table class="panel-table">
+            <tr>
+                <td><label class="ui-text-label">Platform</label></td>
+                <td><select id="platform-select" class="ui-state-default ui-corner-all"></select></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">Version</label></td>
+                <td><select id="version-select" class="ui-state-default ui-corner-all"></select></td>
+            </tr>
+        </table>
+        
+        <button id="change-platform" class="PanelButtonStyle">
+            <span class="ui-button-text">Change Platform</span>
+        </button>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="information-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>System Summary</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+    <section id="information-sub-container" class="info ui-widget-content ui-corner-all" style="display: none;"></section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="phone-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Phone</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section class="info ui-widget-content ui-corner-all" style="display: none">
+        <table class="panel-table">
+            <tr>
+                <td><label class="ui-text-label">Type</label></td>
+                <td><select id="phone-event-types" class="ui-state-default ui-corner-all"></select></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">Call id</label></td>
+                <td><input id="phone-call-id" type="text" class="ui-state-default ui-corner-all"></td>
+            </tr>
+            <tr id="phone-event-error-container" style="display: none">
+                <td><label class="ui-text-label">Error</label></td>
+                <td><select id="phone-event-error-types" class="ui-state-default ui-corner-all"></select></td>
+            </tr>
+       </table>
+       <table class="panel-table">
+            <tr>
+                <td>
+                    <button id="phone-logs-clear" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+                        <span class="ui-button-text">Clear Logs</span>
+                    </button>
+                </td>
+                <td>
+                    <button id="phone-event-send" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+                        <span class="ui-button-text">Fire Event</span>
+                    </button>
+                </td>
+            </tr>
+        </table>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="multimedia-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Multimedia</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+    <section id="media-container" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <h3>Multimedia</h3>
+
+        <table class="panel-table">
+            <tr>
+                <td><label class="ui-text-label">Is audio playing?</label></td>
+                <td id="multimedia-isaudioplaying">false</td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">Is video playing?</label></td>
+                <td id="multimedia-isvideoplaying">false</td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">Volume:</label></td>
+                <td>
+                    <span id="media-volume-value" class="range-label-right">05</span>
+                    <input id="media-volume" type="range" min="0" max="10" value="5" />
+                </td>
+            </tr>
+        </table>
+
+        <h3>Audio Player</h3>
+
+        <table class="panel-table audio-table">
+            <tr>
+                <td><label class="ui-text-label">Opened File:</label></td>
+                <td id="media-audio-file"></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">State:</label></td>
+                <td id="media-audio-state"></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">Progress:</label></td>
+                <td id="media-audio-progress"></td>
+            </tr>
+        </table>
+
+        <h3>Video Player</h3>
+
+        <table class="panel-table video-table">
+            <tr>
+                <td><label class="ui-text-label">Opened File:</label></td>
+                <td id="media-video-file"></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">State:</label></td>
+                <td id="media-video-state"></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">Progress:</label></td>
+                <td id="media-video-progress"></td>
+            </tr>
+        </table>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="application-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Application</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section class="info ui-widget-content ui-corner-all" style="display: none;">
+    <div><span class="PanelSectionTitle">Installed applications</span></div>
+    <div data-role="page" id="page1">
+        <div data-role="content" value="A">
+            <select id="application-installed" class="ui-state-default ui-corner-all"></select>
+        </div>
+    </div>
+    <p></p>
+    <div align="center">
+        <button id="application-install" class="PanelButtonStyle">Install</button>
+        <button id="application-update" class="PanelButtonStyle">Update</button>
+        <button id="application-uninstall" class="PanelButtonStyle">Uninstall</button>
+    </div>
+
+
+        <table id= "application-table" class="panel-table">
+            <tr><td colspan=2><hr width="100%"></td></tr>
+            <tr>
+                <td><label class="ui-text-label" for="application-id">ID</label></td>
+                <td><input id="application-id" class="ui-state-default ui-corner-all" type="text" maxlength="100"></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label" for="application-name">Name</label></td>
+                <td><input id="application-name" class="ui-state-default ui-corner-all" type="text" maxlength="100"></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label" for="application-iconPath">Icon path</label></td>
+                <td><input id="application-iconPath" class="ui-state-default ui-corner-all" type="text" maxlength="100"></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label" for="application-iconPath">Version</label></td>
+                <td><input id="application-version" class="ui-state-default ui-corner-all" type="text" maxlength="100"></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label" for="application-show">Show</label></td>
+                <td>
+                    <label>Yes</label><input type="radio" name="application-show" checked="checked" value="true" />
+                    <label>No</label><input type="radio" name="application-show" value="false" />
+                </td>
+            </tr>
+
+            <tr><td colspan=2><hr width="100%"></td></tr>
+            <tr>
+                <td colspan=2><label class="ui-text-label">Binding service</label></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label" for="application-operation">Service operation</label></td>
+                <td><input id="application-operation" class="ui-state-default ui-corner-all" type="text" maxlength="100"></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label" for="application-uri">Service URI</label></td>
+                <td><input id="application-uri" class="ui-state-default ui-corner-all" type="text" maxlength="100"></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label" for="application-mime">Service MIME</label></td>
+                <td><input id="application-mime" class="ui-state-default ui-corner-all" type="text" maxlength="100"></td>
+            </tr>
+
+        </table>
+    </section>
+</section>
+
+/!--
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+--/
+
+<section id="time-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Time Zone</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+    <section class="info ui-widget-content ui-corner-all" style="display: none;">
+        <h3 class="PanelSectionTitle">Current Time Locale</h3>
+        <select id="time-locale-select" class="ui-state-default ui-corner-all"></select>
+        <br/><br/>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="power-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Power Manager</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section class="info ui-widget-content ui-corner-all" style="display: none;">
+        <span class="PanelSectionTitle">Resources</span>
+            <br/><br/>
+            <table class="tf_panel-table" style="border-spacing: 0px;">
+                <tr>
+                    <td style="text-align:left"><label class="ui-text-label" id="cpu-load-label">CPU:(load = 0.9)</label></td>
+                </tr>
+                <tr>
+                    <td style="text-align:left"> 
+                        <select id="cpu-state" class="ui-state-default ui-corner-all" style="width:60%; align:center">
+                            <option value="LOW">Low</option>
+                            <option value="HIGH">High</option>
+                        </select>
+                    </td>
+                </tr>
+            </table>
+            <br/>
+            <span><label class="ui-text-label">Power Management Rules</label></span><br/><br/>
+            <table class="tf_panel-table" style="border-spacing: 0px;">
+                <tr>
+                    <td style="text-align:left">High</td>
+                    <td style="text-align:left">
+                        <select id="high-role" class="ui-state-default ui-corner-all" >
+                            <option value='1'>Allow</option>
+                            <option value='0'>Deny</option>
+                        </select>
+                    </td>
+                </tr>
+                <tr>
+                    <td style="text-align:left">Low</td>
+                    <td style="text-align:left">
+                        <select id="low-role" class="ui-state-default ui-corner-all" >
+                            <option value='1'>Allow</option>
+                            <option value='0'>Deny</option>
+                        </select>
+                    </td>
+                </tr>
+            </table>
+            <br/>
+            <div>---------------------------------------------------------------------</div>
+            <div ></div>
+            <br/>
+            <table class="tf_panel-table" style="border-spacing: 0px;">
+                <tr>
+                    <td style="text-align:left"><label class="ui-text-label" id="diplay-brightness-label">Display:(brightness = 0.3)</label></td>
+                </tr>
+                <tr>
+                    <td style="text-align:left"> 
+                        <select id="display-state" class="ui-state-default ui-corner-all" style="width:60%; align:center">
+                            <option value="OFF">Off</option>
+                            <option value="DIM">Dim</option>
+                            <option value="NORMAL">Normal</option>
+                            <option value="BRIGHT">Bright</option>
+                        </select>
+                    </td>
+                </tr>
+            </table>
+            <br/>
+            <span><label class="ui-text-label">Power Management Rules</label></span><br/><br/>
+            <table class="tf_panel-table" style="border-spacing: 0px;">
+                <tr>
+                    <td style="text-align:left">Off</td>
+                    <td style="text-align:left">
+                        <select id="off-role" class="ui-state-default ui-corner-all" >
+                            <option value='1'>Allow</option>
+                            <option value='0'>Deny</option>
+                        </select>
+                    </td>
+                </tr>
+                <tr>
+                    <td style="text-align:left">Dim</td>
+                    <td style="text-align:left">
+                        <select id="dim-role" class="ui-state-default ui-corner-all" >
+                            <option value='1'>Allow</option>
+                            <option value='0'>Deny</option>
+                        </select>
+                    </td>
+                </tr>
+                <tr>
+                    <td style="text-align:left">Normal</td>
+                    <td style="text-align:left">
+                        <select id="normal-role" class="ui-state-default ui-corner-all" >
+                            <option value='1'>Allow</option>
+                            <option value='0'>Deny</option>
+                        </select>
+                    </td>
+                </tr>
+                <tr>
+                    <td style="text-align:left">Bright</td>
+                    <td style="text-align:left">
+                        <select id="bright-role" class="ui-state-default ui-corner-all" >
+                            <option value='1'>Allow</option>
+                            <option value='0'>Deny</option>
+                        </select>
+                    </td>
+                </tr>
+            </table>
+         
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="battery-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Battery</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section class="info ui-widget-content ui-corner-all" style="display: none;">
+        <table class="panel-table">
+            <tr>
+                <td colspan="2"  align="center">
+                    <p id='error-comment' style="DISPLAY:none;color:red">Only number between 1 to 600 is accepted. Try again.</p>
+                </td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">Total Time (mins)</label></td>
+                <td><input id="charging-time" type="text" value="1" class="ui-state-default ui-corner-all"></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">Battery Level</label></td>
+                <td>
+                    <label id="battery-volume-label" class="range-label-left">100%</label>
+                    <input id="battery-volume" type="range" value="100" min="0" max="100" step="0.01" class="ui-state-default ui-corner-all">
+                </td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">Remaining Power (mins)</label></td>
+                <td id="battery-remaining-power" style="width:300px"></td>
+            </tr>
+            <tr>
+                <td>
+                    <span class="ui-text-label">Is Charging</span>
+                </td>
+                <td>
+                    <input id="is-charging" type="checkbox" />
+                </td>
+            </tr>
+        </table>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="accelerometer-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Accelerometer</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+    <section id="accelerometer" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <section class="accelerometer-info">
+            <canvas style="display: block;" id="accelerometer-canvas" width="300" height="200"></canvas>
+
+            <table class="tf_panel-table">
+                <tr>
+                    <td colspan="2" style="text-align: center"> 
+                        <em>
+                            Click and drag with the mouse to manipulate the device. <br/>
+                            Hold the Shift key to modify 'alpha'.
+                        </em>
+                    </td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label" for="accelerometer-x">xAxis:</label></td>
+                    <td><span id="accelerometer-x"></span> m/s^2</td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label" for="accelerometer-y">yAxis:</label></td>
+                    <td><span id="accelerometer-y"></span> m/s^2</td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label" for="accelerometer-z">zAxis:</label></td>
+                    <td><span id="accelerometer-z"></span> m/s^2</td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label" for="accelerometer-alpha">alpha:</label></td>
+                    <td><span id="accelerometer-alpha"></span> deg</td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label" for="accelerometer-beta">beta:</label></td>
+                    <td><span id="accelerometer-beta"></span> deg</td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label" for="accelerometer-gamma">gamma:</label></td>
+                    <td><span id="accelerometer-gamma"></span> deg</td>
+                </tr>
+                <tr>
+                    <td></td>
+                    <td>
+                        <button id="accelerometer-shake" class="PanelButtonStyle">
+                        <span class="ui-button-text">Shake</span>
+                        </button>
+                    </td>
+                </tr>
+            </table>
+        </section>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="messaging-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Messaging</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section id="messaging" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <section class="messaging-info">
+               <span class="PanelSectionTitle">Sending</span>
+            <table id="messaging-sms-fields" class="tf_panel-table">
+                <tr>
+                    <td><label class="ui-text-label">From</label></td>
+                    <td style="width:80%;"><input id="messaging-sms-number" type="text" class="ui-corner-all" style="width: 88%;"></td>
+                </tr>
+                
+                <tr>
+                    <td><label class="ui-text-label">Type</label></td>
+                    <td><select id="messaging-type" class="ui-state-default ui-corner-all"></select></td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label">Text</label></td>
+                    <td><textarea class="ui-corner-all" id="messaging-text" rows="6" style="width: 88%;"></textarea></td>
+                </tr>
+<!-- TODO: add back when attachment is finished
+                <tr>
+                    <td><label class="ui-text-label">Attachment Content</label></td>
+                    <td><textarea class="ui-corner-all" id="messaging-attachment-content" rows="6" style="width: 88%;"></textarea></td>
+                </tr>
+                <tr>
+                       <td><table id="messaging-attachments" class="tf_panel-table"></table></td>
+                       <td><span><button id="messaging-attach" class="PanelButtonStyle">Attach</button>&nbsp;&nbsp;<button id="messaging-detach" class="PanelButtonStyle">Detach</button></span></td>
+                </tr>
+-->
+                <tr>
+                <td></td>
+                <td>
+                       <button id="messaging-send" class="PanelButtonStyle" style="width:200px;">Send</button>
+                </td>
+                </tr>
+            </table>
+                       <br>
+                       <span class="PanelSectionTitle">Receiving</span>
+                       <table class="tf_panel-table">
+                <tr>
+                    <td><label class="ui-text-label">Recipients</label></td>
+                    <td><input id="messaging-recipients" type="text" class="ui-corner-all" style="width: 28%;">&nbsp;&nbsp;<span id="messaging-received"></span></td>
+                </tr>
+                <tr>
+                    <td><label class="ui-text-label">Message</label></td>
+                    <td><label class="ui-text-label"><textarea  class="ui-corner-all" id="received-message-box" rows="3" style="width: 90%;" readonly></textarea></label></td>
+                </tr>
+                <tr>
+                    <td></td>
+                    <td><button class="PanelButtonStyle" id="messaging-clear">Clear</button></td>
+                </tr>
+            </table>
+        </section>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="devicesettings-panel-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Device &amp; Network Settings</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section id="devicesettings-content-container" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <p>Configure device information, settings, and events for the current platform.</p>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="settings-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Device UI Settings</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+    <section class="info ui-widget-content ui-corner-all" style="display: none;">
+        <table class="panel-table">
+            <tr>
+                <td><label class="ui-text-label">Tooltips</label></td>
+                <td>
+                    <button id="settings-toggletooltips" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+                        <span class="ui-button-text">Toggle</span>
+                    </button>
+                </td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">Cross Domain Proxy</label></td>
+                <td>
+                    <select id="settings-xhr-proxy" class="ui-state-default ui-corner-all">
+                        <option value="false">Enabled</option>
+                        <option value="true">Disabled</option>
+                    </select>
+                </td>
+            </tr>
+            <tr class="theme-switcher">
+                <td><label class="ui-text-label">Themes</label></td>
+                <td><select id="theme-select" class="ui-state-default ui-corner-all"></select></td>
+            </tr>
+        </table>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="push-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Push</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section id="push" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <section class="push-info">
+            <table id="push-fields" class="panel-table">
+                <tr>
+                    <td><label class="ui-text-label">Port</label></td>
+                    <td><select id="port-select" class="ui-state-default ui-corner-all"></select></td>
+                </tr>
+            </table>
+
+            <table class="panel-table">
+                <tr>
+                    <td colspan="2">
+                        <textarea class="ui-state-default ui-corner-all" id="push-text" rows="4" style="width: 90%;"></textarea>
+                    </td>
+                </tr>
+
+                <tr>
+                    <td colspan="2">
+                        <button id="push-send" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+                            <span class="ui-button-text">Push</span>
+                        </button>
+                    </td>
+                </tr>
+            </table>
+        </section>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="platform-events-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Events</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section id="platform-events-container" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <p>Select the event that you want to fire.</p>
+        <select id="platform-events-select" class="ui-state-default ui-corner-all"></select>
+        <select id="platform-events-args" class="ui-state-default ui-corner-all" style="display: none"></select>
+        <br />
+        <button id="platform-events-fire" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+            <span class="ui-button-text">Fire Event</span>
+        </button>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="config-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Feature Configuration</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section class="info ui-widget-content ui-corner-all" style="display: none;">
+        <p>
+            This section is a graphical representation of your configuration file. It is color coded to indicate success / failure.
+            Expand each node to see the details.
+        </p>
+
+        <p>
+            The colors represent the following:
+        </p>
+
+        <ul>
+            <li class="ui-text-pass">Validation passed</li>
+            <li class="ui-text-fail">Validation failed</li>
+            <li class="ui-text-missing">Node is missing, but not required</li>
+        </ul>
+        <section id="widget-config"></section>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="geoDB-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Geo Database</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section class="info ui-widget-content ui-corner-all" style="display: none;">
+    <p></p><select id="geo-select" class="ui-state-default ui-corner-all"></select>
+
+
+        <table id= "geoDB-table" class="panel-table">
+            <tr>
+                <td colspan=2>
+    <button id="geoDB-add" class="geo-map-zoom-btn ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" ><span class="ui-button-text">Add</span></button>
+    <button id="geoDB-modify" class="geo-map-zoom-btn ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" ><span class="ui-button-text">Modify</span></button>
+    <button id="geoDB-delete" class="geo-map-zoom-btn ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" ><span class="ui-button-text">Delete</span></button>
+                    <button id="geoDB-save" class="geo-map-zoom-btn ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" ><span class="ui-button-text">Save</span></button>
+                    <button id="geoDB-cancel" class="geo-map-zoom-btn ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" ><span class="ui-button-text">Cancel</span></button>
+                </td>
+            </tr>
+            <tr>
+                <td><label id="label-geoDB-latitude" class="ui-text-label" for="geoDB-latitude">Latitude</label></td>
+                <td><input id="geoDB-latitude" class="ui-state-default ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr>
+                <td><label id="label-geoDB-longitude" class="ui-text-label" for="geoDB-longitude">Longitude</label>
+                </td>
+                <td><input id="geoDB-longitude" class="ui-state-default ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr>
+                <td><label id="label-geoDB-altitude" class="ui-text-label" for="geoDB-altitude">Altitude</label></td>
+                <td><input id="geoDB-altitude" class="ui-state-default ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr>
+                <td><label id="label-geoDB-accuracy" class="ui-text-label" for="geoDB-accuracy">Accuracy</label></td>
+                <td><input id="geoDB-accuracy" class="ui-state-default ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr>
+                <td><label id="label-geoDB-altitudeaccuracy" class="ui-text-label" for="geoDB-altitudeAccuracy">Altitude Accuracy</label></td>
+                <td><input id="geoDB-altitudeAccuracy" class="ui-state-default ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr>
+                <td><label id="label-geoDB-heading" class="ui-text-label" for="geoDB-heading">Heading</label></td>
+                <td><input id="geoDB-heading" type="number" value="" class="ui-state-default ui-corner-all"></td>
+            </tr>
+            <tr>
+                <td><label id="label-geoDB-speed" class="ui-text-label" for="geoDB-speed">Speed</label></td>
+                <td><input id="geoDB-speed" class="ui-state-default ui-corner-all" type="number" value=""></td>
+            </tr>
+            <tr><td colspan=2><hr width="100%"></td></tr>
+            <tr>
+                <td><label id="label-geoDB-country" class="ui-text-label" for="geoDB-country">country</label></td>
+                <td><input id="geoDB-country" class="ui-state-default ui-corner-all" type="string" value=""></td>
+            </td>
+            <tr>
+                <td><label id="label-geoDB-region" class="ui-text-label" for="geoDB-region">region</label></td>
+                <td><input id="geoDB-region" class="ui-state-default ui-corner-all" type="string" value=""></td>
+            </td>
+            <tr>
+                <td><label id="label-geoDB-county" class="ui-text-label" for="geoDB-county">county</label></td>
+                <td><input id="geoDB-county" class="ui-state-default ui-corner-all" type="string" value=""></td>
+            </td>
+            <tr>
+                <td><label id="label-geoDB-city" class="ui-text-label" for="geoDB-city">city</label></td>
+                <td><input id="geoDB-city" class="ui-state-default ui-corner-all" type="string" value=""></td>
+            </td>
+            <tr>
+                <td><label id="label-geoDB-street" class="ui-text-label" for="geoDB-street">street</label></td>
+                <td><input id="geoDB-street" class="ui-state-default ui-corner-all" type="string" value=""></td>
+            </td>
+            <tr>
+                <td><label id="label-geoDB-streetNumber" class="ui-text-label" for="geoDB-streetNumber">streetNumber</label></td>
+                <td><input id="geoDB-streetNumber" class="ui-state-default ui-corner-all" type="string" value=""></td>
+            </td>
+            <tr>
+                <td><label id="label-geoDB-premises" class="ui-text-label" for="geoDB-premises">premises</label></td>
+                <td><input id="geoDB-premises" class="ui-state-default ui-corner-all" type="string" value=""></td>
+            </td>
+            <tr>
+                <td><label id="label-geoDB-additionalInformation" class="ui-text-label" for="geoDB-additionalInformation">additionalInformation</label></td>
+                <td><input id="geoDB-additionalInformation" class="ui-state-default ui-corner-all" type="string" value=""></td>
+            </td>
+            <tr>
+                <td><label id="label-geoDB-postalCode" class="ui-text-label" for="geoDB-postalCode">postalCode</label></td>
+                <td><input id="geoDB-postalCode" class="ui-state-default ui-corner-all" type="string" value=""></td>
+            </td>
+        </table>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="filesystem-container" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>File System</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section id="file-container" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <p>You can map the following virtual paths (ex. /virtual/photos/) to specific locations on your drive.</p>
+
+        <p>You may specify any valid URI location (ex. http://domain.com/files).</p>
+
+        <p>Empty values will cause the virtual routes to point to your relative location.</p>
+
+        <p class="ui-text-label" >/virtual/...</p>
+
+        <table class="panel-table">
+            <tr>
+                <td><label class="ui-text-label">photos/</label></td>
+                <td><input id="panel-filesystem-photos" class="ui-state-default ui-corner-all" type="text" value=""/></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">videos/</label></td>
+                <td><input id="panel-filesystem-videos" class="ui-state-default ui-corner-all" type="text" value=""/></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">music/</label></td>
+                <td><input id="panel-filesystem-music" class="ui-state-default ui-corner-all" type="text" value=""/></td>
+            </tr>
+            <tr>
+                <td><label class="ui-text-label">downloads/</label></td>
+                <td><input id="panel-filesystem-downloads" class="ui-state-default ui-corner-all" type="text" value=""/></td>
+            </tr>
+        </table>
+    </section>
+</section>
+
+<!--
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<section id="preferences" class="ui-box ui-state-default">
+    <section class="h2 info-header">
+        <section class="collapse-handle"><span class="ui-box-TitleImage ui-box-TitleImageClosed"></span>Storage</section>
+        <section class="drag-handle">
+            <span><img src="images/menuDraggerIcon.png"/></span>
+        </section>
+    </section>
+
+    <section id="preferences-list" class="info ui-widget-content ui-corner-all" style="display: none;">
+        <table class="preferences-table ui-widget-content">
+            <thead><tr><th><label class="ui-text-label">Key</label></th><th><label class="ui-text-label">Value</label></th></tr></thead>
+            <tbody id="preferences-list-body"></tbody>
+        </table>
+
+        <section class="preferences-count" id="preferences-count"></section>
+        <span class="preferences-count">Total:&nbsp;</span>
+        <span class="ui-text-highlight preferences-note">(read-only preference colour)</span><br/>
+
+        <button id="preferences-clear-button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+            <span class="ui-button-text">Clear All</span>
+        </button>
+    </section>
+</section>
+
+</section>
+            <section id="dialog-views" class="irrelevant"><section id="settings-dialog">
+       <div id="settings-tabs">
+               <ul>
+            <li><a href="#settings-tabs-build">Package</a></li>
+               </ul>
+        <div id="settings-tabs-build">
+        </div>
+       </div>
+    <button id="settings-action" class="cap-text" style="float: right"></button>
+</section>
+
+<div id="about-dialog" style="background: #ffffff; padding:0; margin-left:0;" class="ui-state-default ui-corner-bottom" align="center" title="About Tizen Web Simulator">
+  <div style="padding:0; margin-left:0;"><image src="images/about_Tizen_Simulator_logo.png">
+  <div id="about-dialog-ripple-version" style="font-size: 13pt; font-color:#333; font-weight: semi-bold; margin-top:20px;">Version: 2.0.0a2</div>
+  <div style="font-size: 10pt; font-color:#333; font-weight: semi-bold;">Aug 29, 2012</div>
+  <p style="font-size: 12pt; font-color:#333; margin-top:18px; line-height:21px;">
+  Based on the <a style="font-size:12px; color:rgb(46,171,171); text-decoration: none;" href="http://rippledocs.tinyhippos.com/index.html">Ripple Mobile Emulator</a><br>
+   Copyright 2012 Intel Corporation. All rights reserved
+    <a style="font-size:12px; color:rgb(46,171,171); text-decoration: none;" href="https://developer.tizen.org" target="_blank"><u>https://developer.tizen.org</u></a>
+  </p>
+</div>
+
+</section>
+
+            <div class="platform-select-dialog main ui-corner-all">
+                <section class="platform-select-logo"></section>
+                <section class="platform-select-text">
+                    <h2>Are you ready for this?!?!</h2>
+                    <p>You're seeing this window because this is the first time you've enabled for this specific URL. Please select the platform/runtime you wish to start testing with.</p>
+                    <br />
+                    <section class="platform-select-buttons">
+                    </section>
+                </section>
+            </div>
+        </section>
+        <script src="ripple.js" type="text/javascript"></script>
+    </body>
+</html>
diff --git a/web/ripple.js b/web/ripple.js
new file mode 100644 (file)
index 0000000..5cc9843
--- /dev/null
@@ -0,0 +1,75968 @@
+/*! 
+  Ripple Mobile Environment Emulator v0.9.2 :: Built On Wed Sep 05 2012 10:14:42 GMT+0800 (CST)
+
+                                Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+-------------------------------------------------------
+Copyright 2011 Research In Motion Limited.
+
+Contributors:
+        Brent Lintner (blintner@rim.com)
+        Dan Silivestru (dsilivestru@rim.com)
+        Gord Tanner (gtanner@rim.com)
+        Nino D'Aversa (ndaversa@rim.com)
+        Nukul Bhasin (nbhasin@rim.com)
+
+-------------------------------------------------------
+--> Kudos to third party awesomeness:
+
+* browser-require *
+
+https://github.com/rsms/browser-require
+
+The MIT License
+http://www.opensource.org/licenses/mit-license.php
+Copyright (c) 2010 Rasmus Andersson http://hunch.se/
+
+-------------------------------------------------------
+* jWorkflow *
+
+http://github.com/tinyhippos/jWorkflow/
+
+The MIT License
+http://www.opensource.org/licenses/mit-license.php
+Copyright (c) 2010 all contributors:
+Gord Tanner
+
+-------------------------------------------------------
+* jXHR.js (JSON-P XHR) *
+ v0.1 (c) Kyle Simpson 
+ MIT License
+
+-------------------------------------------------------
+* UI.Acceleromter Control (panel plugin) *
+
+Licensed under the MIT license:
+  Copyright Train Hack 2010
+  Contributors: Wolfram Kriesing, Dan Silivestru, Brent Lintner
+  http://www.opensource.org/licenses/mit-license.php
+
+-------------------------------------------------------
+* jQuery JavaScript Library *
+
+http://jquery.com/
+
+Copyright 2010, John Resig
+Licensed under MIT
+http://jquery.org/license
+
+Includes Sizzle.js
+http://sizzlejs.com/
+Copyright 2010, The Dojo Foundation
+Released under the MIT, BSD, and GPL Licenses.
+
+-------------------------------------------------------
+* jQuery UI *
+
+Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
+licensed under the MIT (MIT-LICENSE.txt)
+
+http://docs.jquery.com/UI
+
+-------------------------------------------------------
+* jQuery Tooltip plugin *
+
+http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
+http://docs.jquery.com/Plugins/Tooltip
+
+Copyright (c) 2006 - 2008 Jörn Zaefferer
+
+Dual licensed under the MIT and GPL licenses:
+  http://www.opensource.org/licenses/mit-license.php
+  http://www.gnu.org/licenses/gpl.html
+
+-------------------------------------------------------
+* Math.uuid.js (v1.4) *
+
+http://www.broofa.com
+mailto:robert@broofa.com
+
+Copyright (c) 2010 Robert Kieffer
+Dual licensed under the MIT and GPL licenses.
+
+-------------------------------------------------------
+* Wii Opera SDK - 3D Math Class v2.7.22 2008-12-14 *
+(c) 2007-2008 Daniel Gump. All Rights Reserved.                          
+ http://wiioperasdk.com, http://hullbreachonline.com                      
+ hullbreach@hullbreachonline.com                                          
+                                                                          
+* Wii Opera SDK - Drawing Class v2.6.16 2008-12-14 * 
+(c) 2007-2008 Daniel Gump. All Rights Reserved
+http://wiioperasdk.com, http://hullbreachonline.com
+hullbreach@hullbreachonline.com
+
+  Wii is a trademark of Nintendo Co., Ltd.                                
+  Opera is a trademark of Opera, ASA.                                     
+  This software package is not associated with either company             
+  but was created to support users of both.  Its alternative name         
+  when supporting other products is the HULLBREACH SDK.                   
+                                                                          
+  Redistribution and use in source and binary forms, with or without      
+  modification, are permitted provided that the following conditions      
+  are met:                                                                
+    * Redistributions of source code must retain the above copyright      
+      notice, this list of conditions and the following disclaimer.       
+    * Redistributions in binary form must reproduce the above copyright   
+      notice, this list of conditions and the following disclaimer in     
+      the documentation and/or other materials provided with the          
+      distribution.                                                       
+    * Neither the names HULLBREACH ONLINE nor WII OPERA SDK nor the names 
+      of its contributors may be used to endorse or promote products      
+      derived from this software without specific prior written           
+      permission.                                                         
+    * If the explicit purpose of the software is not to support the       
+      Nintendo Wii or the Opera Web browser, then the names of such must  
+      not be used in any derived product. The name shall be the           
+      HULLBREACH SDK with a reference link to http://hullbreachonline.    
+                                                                          
+  THIS SOFTWARE IS PROVIDED BY Daniel Gump ''AS IS'' AND ANY EXPRESS OR   
+  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  
+  DISCLAIMED. IN NO EVENT SHALL Daniel Gump BE LIABLE FOR ANY DIRECT,     
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      
+  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      
+  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     
+  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   
+  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      
+  POSSIBILITY OF SUCH DAMAGE.                                             
+
+-------------------------------------------------------
+  OpenLayers.js -- OpenLayers Map Viewer Library
+
+  Copyright 2005-2010 OpenLayers Contributors, released under the Clear BSD
+  license. Full license text below taken from http://svn.openlayers.org/trunk/openlayers/license.txt
+
+        Copyright 2005-2011 OpenLayers Contributors. All rights reserved. See
+        authors.txt for full list.
+         
+        Redistribution and use in source and binary forms, with or without modification,
+        are permitted provided that the following conditions are met:
+         
+        1. Redistributions of source code must retain the above copyright notice, this
+        list of conditions and the following disclaimer.
+         
+        2. Redistributions in binary form must reproduce the above copyright notice,
+        this list of conditions and the following disclaimer in the documentation and/or
+        other materials provided with the distribution.
+         
+        THIS SOFTWARE IS PROVIDED BY OPENLAYERS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
+        OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+        MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+        SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+        INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+        LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+        PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+        LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+        OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+        ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+         
+        The views and conclusions contained in the software and documentation are those
+        of the authors and should not be interpreted as representing official policies,
+        either expressed or implied, of OpenLayers Contributors.
+
+  Includes compressed code under the following licenses:
+
+  (For uncompressed versions of the code used please see the
+  OpenLayers SVN repository: <http://openlayers.org/>)
+
+-------------------------------------------------------
+  Contains portions of Rico <http://openrico.org/>
+  Copyright 2005 Sabre Airline Solutions  
+  
+  Licensed under the Apache License, Version 2.0 (the "License"); you
+  may not use this file except in compliance with the License. You
+  may obtain a copy of the License at the top of this file or a the following
+  link:
+  
+         http://www.apache.org/licenses/LICENSE-2.0  
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+  implied. See the License for the specific language governing
+  permissions and limitations under the License. 
+
+-------------------------------------------------------
+  Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>
+  Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  http://www.apache.org/licenses/LICENSE-2.0
+
+-------------------------------------------------------
+  Contains portions of Gears <http://code.google.com/apis/gears/>
+
+  Copyright 2007, Google Inc.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+   3. Neither the name of Google Inc. nor the names of its contributors may be
+      used to endorse or promote products derived from this software without
+      specific prior written permission.
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  Sets up google.gears.*, which is *the only* supported way to access Gears.
+
+  Circumvent this file at your own risk!
+  In the future, Gears may automatically define google.gears.* without this
+  file. Gears may use these objects to transparently fix bugs and compatibility
+  issues. Applications that use the code below will continue to work seamlessly
+  when that happens.
+*/
+// CommonJS compatible module loading.
+// (Except from require.paths, it's compliant with spec 1.1.1.)
+(function(parentExports){
+  // normalize an array of path components
+  function normalizeArray (v, keepBlanks) {
+    var L = v.length, dst = new Array(L), dsti = 0,
+        i = 0, part, negatives = 0,
+        isRelative = (L && v[0] !== '');
+    for (; i<L; ++i) {
+      part = v[i];
+      if (part === '..') {
+        if (dsti > 1) {
+          --dsti;
+        } else if (isRelative) {
+          ++negatives;
+        } else {
+          dst[0] = '';
+        }
+      } else if (part !== '.' && (dsti === 0 || keepBlanks || part !== '')) {
+        dst[dsti++] = part;
+      }
+    }
+    if (negatives) {
+      dst[--negatives] = dst[dsti-1];
+      dsti = negatives + 1;
+      while (negatives--) { dst[negatives] = '..'; }
+    }
+    dst.length = dsti;
+    return dst;
+  }
+  // normalize an id
+  function normalizeId(id, parentId) {
+    id = id.replace(/\/+$/g, '');
+    return normalizeArray((parentId ? parentId + '/../' + id : id).split('/'))
+           .join('/');
+  }
+  // normalize a url
+  function normalizeUrl(url, baseLocation) {
+    if (!(/^\w+:/).test(url)) {
+      var u = baseLocation.protocol+'//'+baseLocation.hostname;
+      if (baseLocation.port && baseLocation.port !== 80) {
+        u += ':'+baseLocation.port;
+      }
+      var path = baseLocation.pathname;
+      if (url.charAt(0) === '/') {
+        url = u + normalizeArray(url.split('/')).join('/');
+      } else {
+        path += ((path.charAt(path.length-1) === '/') ? '' : '/../') + url;
+        url = u + normalizeArray(path.split('/')).join('/');
+      }
+    }
+    return url;
+  }
+  // define a constant (read-only) value property
+  var defineConstant;
+  if (Object.defineProperty) {
+    defineConstant = function (obj, name, value) {
+      Object.defineProperty(obj, name, {value: value, writable: false,
+        enumerable: true, configurable: false});
+    }
+  } else {
+    defineConstant = function (obj, name, value) { obj[name] = value; }
+  }
+  // require/load/import a module
+  // require(id[, parentId]) -> [object module-api]
+  // @throws Error /module not found (json-rep-of-id)/
+  function require (id, parentId) {
+    var originalInputId = id; // for "not found" error message
+    if (id.charAt(0) === '.') {
+      id = normalizeId(id, parentId);
+    }
+    if (!require.modules.hasOwnProperty(id)) {
+      throw new Error('module not found '+JSON.stringify(originalInputId));
+    }
+    var mod = require.modules[id];
+    if (mod.exports === undefined) {
+      var _require = function (_id) {
+        //console.log('_require', _id, 'from', id);
+        return require(_id, id);
+      };
+      defineConstant(_require, 'main', require.main);
+      var block = mod.block; delete mod.block;
+      mod.exports = {};
+      if (require.initFilter) {
+        block = require.initFilter(block);
+      }
+      block(_require, mod, mod.exports);
+    }
+    return mod.exports;
+  }
+  // define a module
+  // define(String id, [String uri,] block(require, module, exports){...})
+  function define (id, uri, block) {
+    if (typeof uri === 'function') {
+      block = uri; uri = null;
+    }
+    var mod = {block: block};
+    defineConstant(mod, 'id', String(id));
+    if (uri) {
+      defineConstant(mod, 'uri', String(uri));
+    }
+    require.modules[mod.id] = mod;
+    return mod;
+  }
+  // modules keyed by id
+  require.modules = {};
+  // search paths -- disabled until we use/need this
+  //require.paths = [];
+  // main module, accessible from require.main
+  var mainModule = define('');
+  delete mainModule.block;
+  mainModule.exports = parentExports;
+  defineConstant(require, 'main', mainModule);
+  // the define function
+  require.define = define;
+  // export the require function
+  parentExports.require = require;
+
+  // -------------------------------------------------------
+  // Optional require.load
+  if (typeof XMLHttpRequest === "undefined") {
+    // we make use of XHR
+    XMLHttpRequest = function () {
+      try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e) {}
+      try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e) {}
+      try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
+      throw new Error("This browser does not support XMLHttpRequest.");
+    };
+  }
+  /**
+   * Load and define a module
+   * load ( spec Object, Function(callback(err Error)) )
+   * load ( specs Array, Function(callback(err Error)) )
+   * load ( url String, Function(callback(err Error)) )
+   */
+  function load (spec, callback) {
+    if ((spec instanceof Array) ||
+        Object.prototype.toString.call(spec) === "[object Array]") {
+      if (callback) {
+        // load multiple and join on callback
+        var countdown = spec.length;
+        for (var i=0;i<spec.length;++i) {(function(u){
+          load(u, function (err) {
+            if (err) {
+              countdown = 0;
+              //throw err;
+              callback(err);
+            } else if (--countdown === 0) {
+              callback();
+            }
+          });
+        })(spec[i]);}
+      } else {
+        // load multiple (blocking) -- don't use this for network resources
+        for (var i=0;i<spec.length;++i) {
+          load(spec[i]);
+        }
+      }
+      return;
+    } else if (typeof spec === 'string') {
+      spec = {url:spec};
+    }
+    if (!spec.url && spec.id) {
+      spec.url = spec.id + '.js';
+    } else if (spec.url && !spec.id) {
+      var m = /^[^\/]+\/\/[^\/]+\/(.+)$/.exec(spec.url);
+      if (m) {
+        spec.id = m[1];
+      } else {
+        spec.id = spec.url;
+      }
+      spec.id = spec.id.replace(/\.[^\.]+$/, '');
+    } else if (!spec.url && !spec.id) {
+      throw new TypeError('missing both "url" and "id"');
+    }
+    // normalize url
+    spec.url = normalizeUrl(spec.url, window.location);
+    var xhr = new XMLHttpRequest();
+    var async = !!callback;
+    function evalResponse() {
+      try {
+        eval('require.define("'+spec.id+'",'+
+             ' "'+spec.url.replace(/"/g, '\\"')+'"'+
+             ', function (require, module, exports) {'+xhr.responseText+'});');
+      } catch (err) {
+        err.message += ' in '+spec.url;
+        throw err;
+      }
+    }
+    xhr.open('GET', spec.url, async);
+    if (async) {
+      xhr.onreadystatechange = function (ev) {  
+        if (xhr.readyState == 4) {
+          if ((xhr.status < 300 && xhr.status >= 200)
+            || (xhr.status === 0 && !spec.url.match(/^(?:https?|ftp):\/\//i))) {
+            try {
+              evalResponse();
+              callback(null);
+            } catch (err) {
+              callback(err);
+            }
+          } else {
+            callback(new Error('failed to load remote module with HTTP'+
+                               ' response status '+xhr.status+' '+
+                               xhr.responseText));
+          }
+        }
+      };
+    }
+    xhr.send(null);
+    if (!async) {
+      evalResponse();
+    }
+  }
+  require.load = load;
+
+})(this);
+/*!
+ * jQuery JavaScript Library v1.6
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * licensed under the MIT 
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon May 2 13:50:00 2011 -0400
+ */
+(function( window, undefined ) {
+
+// Use the correct document accordingly with window argument (sandbox)
+var document = window.document,
+       navigator = window.navigator,
+       location = window.location;
+var jQuery = (function() {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+               // The jQuery object is actually just the init constructor 'enhanced'
+               return new jQuery.fn.init( selector, context, rootjQuery );
+       },
+
+       // Map over jQuery in case of overwrite
+       _jQuery = window.jQuery,
+
+       // Map over the $ in case of overwrite
+       _$ = window.$,
+
+       // A central reference to the root jQuery(document)
+       rootjQuery,
+
+       // A simple way to check for HTML strings or ID strings
+       // (both of which we optimize for)
+       quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+
+       // Check if a string has a non-whitespace character in it
+       rnotwhite = /\S/,
+
+       // Used for trimming whitespace
+       trimLeft = /^\s+/,
+       trimRight = /\s+$/,
+
+       // Check for digits
+       rdigit = /\d/,
+
+       // Match a standalone tag
+       rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+       // JSON RegExp
+       rvalidchars = /^[\],:{}\s]*$/,
+       rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+       rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+       rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+       // Useragent RegExp
+       rwebkit = /(webkit)[ \/]([\w.]+)/,
+       ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
+       rmsie = /(msie) ([\w.]+)/,
+       rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
+       // Keep a UserAgent string for use with jQuery.browser
+       userAgent = navigator.userAgent,
+
+       // For matching the engine and version of the browser
+       browserMatch,
+
+       // The deferred used on DOM ready
+       readyList,
+
+       // The ready event handler
+       DOMContentLoaded,
+
+       // Save a reference to some core methods
+       toString = Object.prototype.toString,
+       hasOwn = Object.prototype.hasOwnProperty,
+       push = Array.prototype.push,
+       slice = Array.prototype.slice,
+       trim = String.prototype.trim,
+       indexOf = Array.prototype.indexOf,
+
+       // [[Class]] -> type pairs
+       class2type = {};
+
+jQuery.fn = jQuery.prototype = {
+       constructor: jQuery,
+       init: function( selector, context, rootjQuery ) {
+               var match, elem, ret, doc;
+
+               // Handle $(""), $(null), or $(undefined)
+               if ( !selector ) {
+                       return this;
+               }
+
+               // Handle $(DOMElement)
+               if ( selector.nodeType ) {
+                       this.context = this[0] = selector;
+                       this.length = 1;
+                       return this;
+               }
+
+               // The body element only exists once, optimize finding it
+               if ( selector === "body" && !context && document.body ) {
+                       this.context = document;
+                       this[0] = document.body;
+                       this.selector = selector;
+                       this.length = 1;
+                       return this;
+               }
+
+               // Handle HTML strings
+               if ( typeof selector === "string" ) {
+                       // Are we dealing with HTML string or an ID?
+                       if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+                               // Assume that strings that start and end with <> are HTML and skip the regex check
+                               match = [ null, selector, null ];
+
+                       } else {
+                               match = quickExpr.exec( selector );
+                       }
+
+                       // Verify a match, and that no context was specified for #id
+                       if ( match && (match[1] || !context) ) {
+
+                               // HANDLE: $(html) -> $(array)
+                               if ( match[1] ) {
+                                       context = context instanceof jQuery ? context[0] : context;
+                                       doc = (context ? context.ownerDocument || context : document);
+
+                                       // If a single string is passed in and it's a single tag
+                                       // just do a createElement and skip the rest
+                                       ret = rsingleTag.exec( selector );
+
+                                       if ( ret ) {
+                                               if ( jQuery.isPlainObject( context ) ) {
+                                                       selector = [ document.createElement( ret[1] ) ];
+                                                       jQuery.fn.attr.call( selector, context, true );
+
+                                               } else {
+                                                       selector = [ doc.createElement( ret[1] ) ];
+                                               }
+
+                                       } else {
+                                               ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+                                               selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
+                                       }
+
+                                       return jQuery.merge( this, selector );
+
+                               // HANDLE: $("#id")
+                               } else {
+                                       elem = document.getElementById( match[2] );
+
+                                       // Check parentNode to catch when Blackberry 4.6 returns
+                                       // nodes that are no longer in the document #6963
+                                       if ( elem && elem.parentNode ) {
+                                               // Handle the case where IE and Opera return items
+                                               // by name instead of ID
+                                               if ( elem.id !== match[2] ) {
+                                                       return rootjQuery.find( selector );
+                                               }
+
+                                               // Otherwise, we inject the element directly into the jQuery object
+                                               this.length = 1;
+                                               this[0] = elem;
+                                       }
+
+                                       this.context = document;
+                                       this.selector = selector;
+                                       return this;
+                               }
+
+                       // HANDLE: $(expr, $(...))
+                       } else if ( !context || context.jquery ) {
+                               return (context || rootjQuery).find( selector );
+
+                       // HANDLE: $(expr, context)
+                       // (which is just equivalent to: $(context).find(expr)
+                       } else {
+                               return this.constructor( context ).find( selector );
+                       }
+
+               // HANDLE: $(function)
+               // Shortcut for document ready
+               } else if ( jQuery.isFunction( selector ) ) {
+                       return rootjQuery.ready( selector );
+               }
+
+               if (selector.selector !== undefined) {
+                       this.selector = selector.selector;
+                       this.context = selector.context;
+               }
+
+               return jQuery.makeArray( selector, this );
+       },
+
+       // Start with an empty selector
+       selector: "",
+
+       // The current version of jQuery being used
+       jquery: "1.6",
+
+       // The default length of a jQuery object is 0
+       length: 0,
+
+       // The number of elements contained in the matched element set
+       size: function() {
+               return this.length;
+       },
+
+       toArray: function() {
+               return slice.call( this, 0 );
+       },
+
+       // Get the Nth element in the matched element set OR
+       // Get the whole matched element set as a clean array
+       get: function( num ) {
+               return num == null ?
+
+                       // Return a 'clean' array
+                       this.toArray() :
+
+                       // Return just the object
+                       ( num < 0 ? this[ this.length + num ] : this[ num ] );
+       },
+
+       // Take an array of elements and push it onto the stack
+       // (returning the new matched element set)
+       pushStack: function( elems, name, selector ) {
+               // Build a new jQuery matched element set
+               var ret = this.constructor();
+
+               if ( jQuery.isArray( elems ) ) {
+                       push.apply( ret, elems );
+
+               } else {
+                       jQuery.merge( ret, elems );
+               }
+
+               // Add the old object onto the stack (as a reference)
+               ret.prevObject = this;
+
+               ret.context = this.context;
+
+               if ( name === "find" ) {
+                       ret.selector = this.selector + (this.selector ? " " : "") + selector;
+               } else if ( name ) {
+                       ret.selector = this.selector + "." + name + "(" + selector + ")";
+               }
+
+               // Return the newly-formed element set
+               return ret;
+       },
+
+       // Execute a callback for every element in the matched set.
+       // (You can seed the arguments with an array of args, but this is
+       // only used internally.)
+       each: function( callback, args ) {
+               return jQuery.each( this, callback, args );
+       },
+
+       ready: function( fn ) {
+               // Attach the listeners
+               jQuery.bindReady();
+
+               // Add the callback
+               readyList.done( fn );
+
+               return this;
+       },
+
+       eq: function( i ) {
+               return i === -1 ?
+                       this.slice( i ) :
+                       this.slice( i, +i + 1 );
+       },
+
+       first: function() {
+               return this.eq( 0 );
+       },
+
+       last: function() {
+               return this.eq( -1 );
+       },
+
+       slice: function() {
+               return this.pushStack( slice.apply( this, arguments ),
+                       "slice", slice.call(arguments).join(",") );
+       },
+
+       map: function( callback ) {
+               return this.pushStack( jQuery.map(this, function( elem, i ) {
+                       return callback.call( elem, i, elem );
+               }));
+       },
+
+       end: function() {
+               return this.prevObject || this.constructor(null);
+       },
+
+       // For internal use only.
+       // Behaves like an Array's method, not like a jQuery method.
+       push: push,
+       sort: [].sort,
+       splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+       var options, name, src, copy, copyIsArray, clone,
+               target = arguments[0] || {},
+               i = 1,
+               length = arguments.length,
+               deep = false;
+
+       // Handle a deep copy situation
+       if ( typeof target === "boolean" ) {
+               deep = target;
+               target = arguments[1] || {};
+               // skip the boolean and the target
+               i = 2;
+       }
+
+       // Handle case when target is a string or something (possible in deep copy)
+       if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+               target = {};
+       }
+
+       // extend jQuery itself if only one argument is passed
+       if ( length === i ) {
+               target = this;
+               --i;
+       }
+
+       for ( ; i < length; i++ ) {
+               // Only deal with non-null/undefined values
+               if ( (options = arguments[ i ]) != null ) {
+                       // Extend the base object
+                       for ( name in options ) {
+                               src = target[ name ];
+                               copy = options[ name ];
+
+                               // Prevent never-ending loop
+                               if ( target === copy ) {
+                                       continue;
+                               }
+
+                               // Recurse if we're merging plain objects or arrays
+                               if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+                                       if ( copyIsArray ) {
+                                               copyIsArray = false;
+                                               clone = src && jQuery.isArray(src) ? src : [];
+
+                                       } else {
+                                               clone = src && jQuery.isPlainObject(src) ? src : {};
+                                       }
+
+                                       // Never move original objects, clone them
+                                       target[ name ] = jQuery.extend( deep, clone, copy );
+
+                               // Don't bring in undefined values
+                               } else if ( copy !== undefined ) {
+                                       target[ name ] = copy;
+                               }
+                       }
+               }
+       }
+
+       // Return the modified object
+       return target;
+};
+
+jQuery.extend({
+       noConflict: function( deep ) {
+               if ( window.$ === jQuery ) {
+                       window.$ = _$;
+               }
+
+               if ( deep && window.jQuery === jQuery ) {
+                       window.jQuery = _jQuery;
+               }
+
+               return jQuery;
+       },
+
+       // Is the DOM ready to be used? Set to true once it occurs.
+       isReady: false,
+
+       // A counter to track how many items to wait for before
+       // the ready event fires. See #6781
+       readyWait: 1,
+
+       // Hold (or release) the ready event
+       holdReady: function( hold ) {
+               if ( hold ) {
+                       jQuery.readyWait++;
+               } else {
+                       jQuery.ready( true );
+               }
+       },
+
+       // Handle when the DOM is ready
+       ready: function( wait ) {
+               // Either a released hold or an DOMready/load event and not yet ready
+               if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
+                       // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+                       if ( !document.body ) {
+                               return setTimeout( jQuery.ready, 1 );
+                       }
+
+                       // Remember that the DOM is ready
+                       jQuery.isReady = true;
+
+                       // If a normal DOM Ready event fired, decrement, and wait if need be
+                       if ( wait !== true && --jQuery.readyWait > 0 ) {
+                               return;
+                       }
+
+                       // If there are functions bound, to execute
+                       readyList.resolveWith( document, [ jQuery ] );
+
+                       // Trigger any bound ready events
+                       if ( jQuery.fn.trigger ) {
+                               jQuery( document ).trigger( "ready" ).unbind( "ready" );
+                       }
+               }
+       },
+
+       bindReady: function() {
+               if ( readyList ) {
+                       return;
+               }
+
+               readyList = jQuery._Deferred();
+
+               // Catch cases where $(document).ready() is called after the
+               // browser event has already occurred.
+               if ( document.readyState === "complete" ) {
+                       // Handle it asynchronously to allow scripts the opportunity to delay ready
+                       return setTimeout( jQuery.ready, 1 );
+               }
+
+               // Mozilla, Opera and webkit nightlies currently support this event
+               if ( document.addEventListener ) {
+                       // Use the handy event callback
+                       document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+                       // A fallback to window.onload, that will always work
+                       window.addEventListener( "load", jQuery.ready, false );
+
+               // If IE event model is used
+               } else if ( document.attachEvent ) {
+                       // ensure firing before onload,
+                       // maybe late but safe also for iframes
+                       document.attachEvent( "onreadystatechange", DOMContentLoaded );
+
+                       // A fallback to window.onload, that will always work
+                       window.attachEvent( "onload", jQuery.ready );
+
+                       // If IE and not a frame
+                       // continually check to see if the document is ready
+                       var toplevel = false;
+
+                       try {
+                               toplevel = window.frameElement == null;
+                       } catch(e) {}
+
+                       if ( document.documentElement.doScroll && toplevel ) {
+                               doScrollCheck();
+                       }
+               }
+       },
+
+       // See test/unit/core.js for details concerning isFunction.
+       // Since version 1.3, DOM methods and functions like alert
+       // aren't supported. They return false on IE (#2968).
+       isFunction: function( obj ) {
+               return jQuery.type(obj) === "function";
+       },
+
+       isArray: Array.isArray || function( obj ) {
+               return jQuery.type(obj) === "array";
+       },
+
+       // A crude way of determining if an object is a window
+       isWindow: function( obj ) {
+               return obj && typeof obj === "object" && "setInterval" in obj;
+       },
+
+       isNaN: function( obj ) {
+               return obj == null || !rdigit.test( obj ) || isNaN( obj );
+       },
+
+       type: function( obj ) {
+               return obj == null ?
+                       String( obj ) :
+                       class2type[ toString.call(obj) ] || "object";
+       },
+
+       isPlainObject: function( obj ) {
+               // Must be an Object.
+               // Because of IE, we also have to check the presence of the constructor property.
+               // Make sure that DOM nodes and window objects don't pass through, as well
+               if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+                       return false;
+               }
+
+               // Not own constructor property must be Object
+               if ( obj.constructor &&
+                       !hasOwn.call(obj, "constructor") &&
+                       !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+                       return false;
+               }
+
+               // Own properties are enumerated firstly, so to speed up,
+               // if last one is own, then all properties are own.
+
+               var key;
+               for ( key in obj ) {}
+
+               return key === undefined || hasOwn.call( obj, key );
+       },
+
+       isEmptyObject: function( obj ) {
+               for ( var name in obj ) {
+                       return false;
+               }
+               return true;
+       },
+
+       error: function( msg ) {
+               throw msg;
+       },
+
+       parseJSON: function( data ) {
+               if ( typeof data !== "string" || !data ) {
+                       return null;
+               }
+
+               // Make sure leading/trailing whitespace is removed (IE can't handle it)
+               data = jQuery.trim( data );
+
+               // Attempt to parse using the native JSON parser first
+               if ( window.JSON && window.JSON.parse ) {
+                       return window.JSON.parse( data );
+               }
+
+               // Make sure the incoming data is actual JSON
+               // Logic borrowed from http://json.org/json2.js
+               if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+                       .replace( rvalidtokens, "]" )
+                       .replace( rvalidbraces, "")) ) {
+
+                       return (new Function( "return " + data ))();
+
+               }
+               jQuery.error( "Invalid JSON: " + data );
+       },
+
+       // Cross-browser xml parsing
+       // (xml & tmp used internally)
+       parseXML: function( data , xml , tmp ) {
+
+               if ( window.DOMParser ) { // Standard
+                       tmp = new DOMParser();
+                       xml = tmp.parseFromString( data , "text/xml" );
+               } else { // IE
+                       xml = new ActiveXObject( "Microsoft.XMLDOM" );
+                       xml.async = "false";
+                       xml.loadXML( data );
+               }
+
+               tmp = xml.documentElement;
+
+               if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
+                       jQuery.error( "Invalid XML: " + data );
+               }
+
+               return xml;
+       },
+
+       noop: function() {},
+
+       // Evaluates a script in a global context
+       // Workarounds based on findings by Jim Driscoll
+       // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+       globalEval: function( data ) {
+               if ( data && rnotwhite.test( data ) ) {
+                       // We use execScript on Internet Explorer
+                       // We use an anonymous function so that context is window
+                       // rather than jQuery in Firefox
+                       ( window.execScript || function( data ) {
+                               window[ "eval" ].call( window, data );
+                       } )( data );
+               }
+       },
+
+       nodeName: function( elem, name ) {
+               return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+       },
+
+       // args is for internal usage only
+       each: function( object, callback, args ) {
+               var name, i = 0,
+                       length = object.length,
+                       isObj = length === undefined || jQuery.isFunction( object );
+
+               if ( args ) {
+                       if ( isObj ) {
+                               for ( name in object ) {
+                                       if ( callback.apply( object[ name ], args ) === false ) {
+                                               break;
+                                       }
+                               }
+                       } else {
+                               for ( ; i < length; ) {
+                                       if ( callback.apply( object[ i++ ], args ) === false ) {
+                                               break;
+                                       }
+                               }
+                       }
+
+               // A special, fast, case for the most common use of each
+               } else {
+                       if ( isObj ) {
+                               for ( name in object ) {
+                                       if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+                                               break;
+                                       }
+                               }
+                       } else {
+                               for ( ; i < length; ) {
+                                       if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
+                                               break;
+                                       }
+                               }
+                       }
+               }
+
+               return object;
+       },
+
+       // Use native String.trim function wherever possible
+       trim: trim ?
+               function( text ) {
+                       return text == null ?
+                               "" :
+                               trim.call( text );
+               } :
+
+               // Otherwise use our own trimming functionality
+               function( text ) {
+                       return text == null ?
+                               "" :
+                               text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
+               },
+
+       // results is for internal usage only
+       makeArray: function( array, results ) {
+               var ret = results || [];
+
+               if ( array != null ) {
+                       // The window, strings (and functions) also have 'length'
+                       // The extra typeof function check is to prevent crashes
+                       // in Safari 2 (See: #3039)
+                       // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
+                       var type = jQuery.type( array );
+
+                       if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
+                               push.call( ret, array );
+                       } else {
+                               jQuery.merge( ret, array );
+                       }
+               }
+
+               return ret;
+       },
+
+       inArray: function( elem, array ) {
+
+               if ( indexOf ) {
+                       return indexOf.call( array, elem );
+               }
+
+               for ( var i = 0, length = array.length; i < length; i++ ) {
+                       if ( array[ i ] === elem ) {
+                               return i;
+                       }
+               }
+
+               return -1;
+       },
+
+       merge: function( first, second ) {
+               var i = first.length,
+                       j = 0;
+
+               if ( typeof second.length === "number" ) {
+                       for ( var l = second.length; j < l; j++ ) {
+                               first[ i++ ] = second[ j ];
+                       }
+
+               } else {
+                       while ( second[j] !== undefined ) {
+                               first[ i++ ] = second[ j++ ];
+                       }
+               }
+
+               first.length = i;
+
+               return first;
+       },
+
+       grep: function( elems, callback, inv ) {
+               var ret = [], retVal;
+               inv = !!inv;
+
+               // Go through the array, only saving the items
+               // that pass the validator function
+               for ( var i = 0, length = elems.length; i < length; i++ ) {
+                       retVal = !!callback( elems[ i ], i );
+                       if ( inv !== retVal ) {
+                               ret.push( elems[ i ] );
+                       }
+               }
+
+               return ret;
+       },
+
+       // arg is for internal usage only
+       map: function( elems, callback, arg ) {
+               var value, key, ret = [],
+                       i = 0,
+                       length = elems.length,
+                       // jquery objects are treated as arrays
+                       isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
+
+               // Go through the array, translating each of the items to their
+               if ( isArray ) {
+                       for ( ; i < length; i++ ) {
+                               value = callback( elems[ i ], i, arg );
+
+                               if ( value != null ) {
+                                       ret[ ret.length ] = value;
+                               }
+                       }
+
+               // Go through every key on the object,
+               } else {
+                       for ( key in elems ) {
+                               value = callback( elems[ key ], key, arg );
+
+                               if ( value != null ) {
+                                       ret[ ret.length ] = value;
+                               }
+                       }
+               }
+
+               // Flatten any nested arrays
+               return ret.concat.apply( [], ret );
+       },
+
+       // A global GUID counter for objects
+       guid: 1,
+
+       // Bind a function to a context, optionally partially applying any
+       // arguments.
+       proxy: function( fn, context ) {
+               if ( typeof context === "string" ) {
+                       var tmp = fn[ context ];
+                       context = fn;
+                       fn = tmp;
+               }
+
+               // Quick check to determine if target is callable, in the spec
+               // this throws a TypeError, but we will just return undefined.
+               if ( !jQuery.isFunction( fn ) ) {
+                       return undefined;
+               }
+
+               // Simulated bind
+               var args = slice.call( arguments, 2 ),
+                       proxy = function() {
+                               return fn.apply( context, args.concat( slice.call( arguments ) ) );
+                       };
+
+               // Set the guid of unique handler to the same of original handler, so it can be removed
+               proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+
+               return proxy;
+       },
+
+       // Mutifunctional method to get and set values to a collection
+       // The value/s can be optionally by executed if its a function
+       access: function( elems, key, value, exec, fn, pass ) {
+               var length = elems.length;
+
+               // Setting many attributes
+               if ( typeof key === "object" ) {
+                       for ( var k in key ) {
+                               jQuery.access( elems, k, key[k], exec, fn, value );
+                       }
+                       return elems;
+               }
+
+               // Setting one attribute
+               if ( value !== undefined ) {
+                       // Optionally, function values get executed if exec is true
+                       exec = !pass && exec && jQuery.isFunction(value);
+
+                       for ( var i = 0; i < length; i++ ) {
+                               fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+                       }
+
+                       return elems;
+               }
+
+               // Getting an attribute
+               return length ? fn( elems[0], key ) : undefined;
+       },
+
+       now: function() {
+               return (new Date()).getTime();
+       },
+
+       // Use of jQuery.browser is frowned upon.
+       // More details: http://docs.jquery.com/Utilities/jQuery.browser
+       uaMatch: function( ua ) {
+               ua = ua.toLowerCase();
+
+               var match = rwebkit.exec( ua ) ||
+                       ropera.exec( ua ) ||
+                       rmsie.exec( ua ) ||
+                       ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
+                       [];
+
+               return { browser: match[1] || "", version: match[2] || "0" };
+       },
+
+       sub: function() {
+               function jQuerySub( selector, context ) {
+                       return new jQuerySub.fn.init( selector, context );
+               }
+               jQuery.extend( true, jQuerySub, this );
+               jQuerySub.superclass = this;
+               jQuerySub.fn = jQuerySub.prototype = this();
+               jQuerySub.fn.constructor = jQuerySub;
+               jQuerySub.sub = this.sub;
+               jQuerySub.fn.init = function init( selector, context ) {
+                       if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+                               context = jQuerySub( context );
+                       }
+
+                       return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+               };
+               jQuerySub.fn.init.prototype = jQuerySub.fn;
+               var rootjQuerySub = jQuerySub(document);
+               return jQuerySub;
+       },
+
+       browser: {}
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
+       class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+       jQuery.browser[ browserMatch.browser ] = true;
+       jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+       jQuery.browser.safari = true;
+}
+
+// IE doesn't match non-breaking spaces with \s
+if ( rnotwhite.test( "\xA0" ) ) {
+       trimLeft = /^[\s\xA0]+/;
+       trimRight = /[\s\xA0]+$/;
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+       DOMContentLoaded = function() {
+               document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+               jQuery.ready();
+       };
+
+} else if ( document.attachEvent ) {
+       DOMContentLoaded = function() {
+               // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+               if ( document.readyState === "complete" ) {
+                       document.detachEvent( "onreadystatechange", DOMContentLoaded );
+                       jQuery.ready();
+               }
+       };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+       if ( jQuery.isReady ) {
+               return;
+       }
+
+       try {
+               // If IE is used, use the trick by Diego Perini
+               // http://javascript.nwbox.com/IEContentLoaded/
+               document.documentElement.doScroll("left");
+       } catch(e) {
+               setTimeout( doScrollCheck, 1 );
+               return;
+       }
+
+       // and execute any waiting functions
+       jQuery.ready();
+}
+
+// Expose jQuery to the global object
+return jQuery;
+
+})();
+
+
+var // Promise methods
+       promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
+       // Static reference to slice
+       sliceDeferred = [].slice;
+
+jQuery.extend({
+       // Create a simple deferred (one callbacks list)
+       _Deferred: function() {
+               var // callbacks list
+                       callbacks = [],
+                       // stored [ context , args ]
+                       fired,
+                       // to avoid firing when already doing so
+                       firing,
+                       // flag to know if the deferred has been cancelled
+                       cancelled,
+                       // the deferred itself
+                       deferred  = {
+
+                               // done( f1, f2, ...)
+                               done: function() {
+                                       if ( !cancelled ) {
+                                               var args = arguments,
+                                                       i,
+                                                       length,
+                                                       elem,
+                                                       type,
+                                                       _fired;
+                                               if ( fired ) {
+                                                       _fired = fired;
+                                                       fired = 0;
+                                               }
+                                               for ( i = 0, length = args.length; i < length; i++ ) {
+                                                       elem = args[ i ];
+                                                       type = jQuery.type( elem );
+                                                       if ( type === "array" ) {
+                                                               deferred.done.apply( deferred, elem );
+                                                       } else if ( type === "function" ) {
+                                                               callbacks.push( elem );
+                                                       }
+                                               }
+                                               if ( _fired ) {
+                                                       deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
+                                               }
+                                       }
+                                       return this;
+                               },
+
+                               // resolve with given context and args
+                               resolveWith: function( context, args ) {
+                                       if ( !cancelled && !fired && !firing ) {
+                                               // make sure args are available (#8421)
+                                               args = args || [];
+                                               firing = 1;
+                                               try {
+                                                       while( callbacks[ 0 ] ) {
+                                                               callbacks.shift().apply( context, args );
+                                                       }
+                                               }
+                                               finally {
+                                                       fired = [ context, args ];
+                                                       firing = 0;
+                                               }
+                                       }
+                                       return this;
+                               },
+
+                               // resolve with this as context and given arguments
+                               resolve: function() {
+                                       deferred.resolveWith( this, arguments );
+                                       return this;
+                               },
+
+                               // Has this deferred been resolved?
+                               isResolved: function() {
+                                       return !!( firing || fired );
+                               },
+
+                               // Cancel
+                               cancel: function() {
+                                       cancelled = 1;
+                                       callbacks = [];
+                                       return this;
+                               }
+                       };
+
+               return deferred;
+       },
+
+       // Full fledged deferred (two callbacks list)
+       Deferred: function( func ) {
+               var deferred = jQuery._Deferred(),
+                       failDeferred = jQuery._Deferred(),
+                       promise;
+               // Add errorDeferred methods, then and promise
+               jQuery.extend( deferred, {
+                       then: function( doneCallbacks, failCallbacks ) {
+                               deferred.done( doneCallbacks ).fail( failCallbacks );
+                               return this;
+                       },
+                       always: function() {
+                               return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
+                       },
+                       fail: failDeferred.done,
+                       rejectWith: failDeferred.resolveWith,
+                       reject: failDeferred.resolve,
+                       isRejected: failDeferred.isResolved,
+                       pipe: function( fnDone, fnFail ) {
+                               return jQuery.Deferred(function( newDefer ) {
+                                       jQuery.each( {
+                                               done: [ fnDone, "resolve" ],
+                                               fail: [ fnFail, "reject" ]
+                                       }, function( handler, data ) {
+                                               var fn = data[ 0 ],
+                                                       action = data[ 1 ],
+                                                       returned;
+                                               if ( jQuery.isFunction( fn ) ) {
+                                                       deferred[ handler ](function() {
+                                                               returned = fn.apply( this, arguments );
+                                                               if ( jQuery.isFunction( returned.promise ) ) {
+                                                                       returned.promise().then( newDefer.resolve, newDefer.reject );
+                                                               } else {
+                                                                       newDefer[ action ]( returned );
+                                                               }
+                                                       });
+                                               } else {
+                                                       deferred[ handler ]( newDefer[ action ] );
+                                               }
+                                       });
+                               }).promise();
+                       },
+                       // Get a promise for this deferred
+                       // If obj is provided, the promise aspect is added to the object
+                       promise: function( obj ) {
+                               if ( obj == null ) {
+                                       if ( promise ) {
+                                               return promise;
+                                       }
+                                       promise = obj = {};
+                               }
+                               var i = promiseMethods.length;
+                               while( i-- ) {
+                                       obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
+                               }
+                               return obj;
+                       }
+               });
+               // Make sure only one callback list will be used
+               deferred.done( failDeferred.cancel ).fail( deferred.cancel );
+               // Unexpose cancel
+               delete deferred.cancel;
+               // Call given func if any
+               if ( func ) {
+                       func.call( deferred, deferred );
+               }
+               return deferred;
+       },
+
+       // Deferred helper
+       when: function( firstParam ) {
+               var args = arguments,
+                       i = 0,
+                       length = args.length,
+                       count = length,
+                       deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
+                               firstParam :
+                               jQuery.Deferred();
+               function resolveFunc( i ) {
+                       return function( value ) {
+                               args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
+                               if ( !( --count ) ) {
+                                       // Strange bug in FF4:
+                                       // Values changed onto the arguments object sometimes end up as undefined values
+                                       // outside the $.when method. Cloning the object into a fresh array solves the issue
+                                       deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
+                               }
+                       };
+               }
+               if ( length > 1 ) {
+                       for( ; i < length; i++ ) {
+                               if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
+                                       args[ i ].promise().then( resolveFunc(i), deferred.reject );
+                               } else {
+                                       --count;
+                               }
+                       }
+                       if ( !count ) {
+                               deferred.resolveWith( deferred, args );
+                       }
+               } else if ( deferred !== firstParam ) {
+                       deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
+               }
+               return deferred.promise();
+       }
+});
+
+
+
+jQuery.support = (function() {
+
+       var div = document.createElement( "div" ),
+               all,
+               a,
+               select,
+               opt,
+               input,
+               marginDiv,
+               support,
+               fragment,
+               body,
+               bodyStyle,
+               tds,
+               events,
+               eventName,
+               i,
+               isSupported;
+
+       // Preliminary tests
+       div.setAttribute("className", "t");
+       div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+       all = div.getElementsByTagName( "*" );
+       a = div.getElementsByTagName( "a" )[ 0 ];
+
+       // Can't get basic test support
+       if ( !all || !all.length || !a ) {
+               return {};
+       }
+
+       // First batch of supports tests
+       select = document.createElement( "select" );
+       opt = select.appendChild( document.createElement("option") );
+       input = div.getElementsByTagName( "input" )[ 0 ];
+
+       support = {
+               // IE strips leading whitespace when .innerHTML is used
+               leadingWhitespace: ( div.firstChild.nodeType === 3 ),
+
+               // Make sure that tbody elements aren't automatically inserted
+               // IE will insert them into empty tables
+               tbody: !div.getElementsByTagName( "tbody" ).length,
+
+               // Make sure that link elements get serialized correctly by innerHTML
+               // This requires a wrapper element in IE
+               htmlSerialize: !!div.getElementsByTagName( "link" ).length,
+
+               // Get the style information from getAttribute
+               // (IE uses .cssText instead)
+               style: /top/.test( a.getAttribute("style") ),
+
+               // Make sure that URLs aren't manipulated
+               // (IE normalizes it by default)
+               hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
+
+               // Make sure that element opacity exists
+               // (IE uses filter instead)
+               // Use a regex to work around a WebKit issue. See #5145
+               opacity: /^0.55$/.test( a.style.opacity ),
+
+               // Verify style float existence
+               // (IE uses styleFloat instead of cssFloat)
+               cssFloat: !!a.style.cssFloat,
+
+               // Make sure that if no value is specified for a checkbox
+               // that it defaults to "on".
+               // (WebKit defaults to "" instead)
+               checkOn: ( input.value === "on" ),
+
+               // Make sure that a selected-by-default option has a working selected property.
+               // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+               optSelected: opt.selected,
+
+               // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+               getSetAttribute: div.className !== "t",
+
+               // Will be defined later
+               submitBubbles: true,
+               changeBubbles: true,
+               focusinBubbles: false,
+               deleteExpando: true,
+               noCloneEvent: true,
+               inlineBlockNeedsLayout: false,
+               shrinkWrapBlocks: false,
+               reliableMarginRight: true
+       };
+
+       // Make sure checked status is properly cloned
+       input.checked = true;
+       support.noCloneChecked = input.cloneNode( true ).checked;
+
+       // Make sure that the options inside disabled selects aren't marked as disabled
+       // (WebKit marks them as disabled)
+       select.disabled = true;
+       support.optDisabled = !opt.disabled;
+
+       // Test to see if it's possible to delete an expando from an element
+       // Fails in Internet Explorer
+       try {
+               delete div.test;
+       } catch( e ) {
+               support.deleteExpando = false;
+       }
+
+       if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
+               div.attachEvent( "onclick", function click() {
+                       // Cloning a node shouldn't copy over any
+                       // bound event handlers (IE does this)
+                       support.noCloneEvent = false;
+                       div.detachEvent( "onclick", click );
+               });
+               div.cloneNode( true ).fireEvent( "onclick" );
+       }
+
+       // Check if a radio maintains it's value
+       // after being appended to the DOM
+       input = document.createElement("input");
+       input.value = "t";
+       input.setAttribute("type", "radio");
+       support.radioValue = input.value === "t";
+
+       input.setAttribute("checked", "checked");
+       div.appendChild( input );
+       fragment = document.createDocumentFragment();
+       fragment.appendChild( div.firstChild );
+
+       // WebKit doesn't clone checked state correctly in fragments
+       support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+       div.innerHTML = "";
+
+       // Figure out if the W3C box model works as expected
+       div.style.width = div.style.paddingLeft = "1px";
+
+       // We use our own, invisible, body
+       body = document.createElement( "body" );
+       bodyStyle = {
+               visibility: "hidden",
+               width: 0,
+               height: 0,
+               border: 0,
+               margin: 0,
+               // Set background to avoid IE crashes when removing (#9028)
+               background: "none"
+       };
+       for ( i in bodyStyle ) {
+               body.style[ i ] = bodyStyle[ i ];
+       }
+       body.appendChild( div );
+       document.documentElement.appendChild( body );
+
+       // Check if a disconnected checkbox will retain its checked
+       // value of true after appended to the DOM (IE6/7)
+       support.appendChecked = input.checked;
+
+       support.boxModel = div.offsetWidth === 2;
+
+       if ( "zoom" in div.style ) {
+               // Check if natively block-level elements act like inline-block
+               // elements when setting their display to 'inline' and giving
+               // them layout
+               // (IE < 8 does this)
+               div.style.display = "inline";
+               div.style.zoom = 1;
+               support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
+
+               // Check if elements with layout shrink-wrap their children
+               // (IE 6 does this)
+               div.style.display = "";
+               div.innerHTML = "<div style='width:4px;'></div>";
+               support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
+       }
+
+       div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
+       tds = div.getElementsByTagName( "td" );
+
+       // Check if table cells still have offsetWidth/Height when they are set
+       // to display:none and there are still other visible table cells in a
+       // table row; if so, offsetWidth/Height are not reliable for use when
+       // determining if an element has been hidden directly using
+       // display:none (it is still safe to use offsets if a parent element is
+       // hidden; don safety goggles and see bug #4512 for more information).
+       // (only IE 8 fails this test)
+       isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+       tds[ 0 ].style.display = "";
+       tds[ 1 ].style.display = "none";
+
+       // Check if empty table cells still have offsetWidth/Height
+       // (IE < 8 fail this test)
+       support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+       div.innerHTML = "";
+
+       // Check if div with explicit width and no margin-right incorrectly
+       // gets computed margin-right based on width of container. For more
+       // info see bug #3333
+       // Fails in WebKit before Feb 2011 nightlies
+       // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+       if ( document.defaultView && document.defaultView.getComputedStyle ) {
+               marginDiv = document.createElement( "div" );
+               marginDiv.style.width = "0";
+               marginDiv.style.marginRight = "0";
+               div.appendChild( marginDiv );
+               support.reliableMarginRight =
+                       ( parseInt( document.defaultView.getComputedStyle( marginDiv, null ).marginRight, 10 ) || 0 ) === 0;
+       }
+
+       // Remove the body element we added
+       body.innerHTML = "";
+       document.documentElement.removeChild( body );
+
+       // Technique from Juriy Zaytsev
+       // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+       // We only care about the case where non-standard event systems
+       // are used, namely in IE. Short-circuiting here helps us to
+       // avoid an eval call (in setAttribute) which can cause CSP
+       // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
+       if ( div.attachEvent ) {
+               for( i in {
+                       submit: 1,
+                       change: 1,
+                       focusin: 1
+               } ) {
+                       eventName = "on" + i;
+                       isSupported = ( eventName in div );
+                       if ( !isSupported ) {
+                               div.setAttribute( eventName, "return;" );
+                               isSupported = ( typeof div[ eventName ] === "function" );
+                       }
+                       support[ i + "Bubbles" ] = isSupported;
+               }
+       }
+
+       return support;
+})();
+
+// Keep track of boxModel
+jQuery.boxModel = jQuery.support.boxModel;
+
+
+
+
+var rbrace = /^(?:\{.*\}|\[.*\])$/,
+       rmultiDash = /([a-z])([A-Z])/g;
+
+jQuery.extend({
+       cache: {},
+
+       // Please use with caution
+       uuid: 0,
+
+       // Unique for each copy of jQuery on the page
+       // Non-digits removed to match rinlinejQuery
+       expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
+
+       // The following elements throw uncatchable exceptions if you
+       // attempt to add expando properties to them.
+       noData: {
+               "embed": true,
+               // Ban all objects except for Flash (which handle expandos)
+               "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+               "applet": true
+       },
+
+       hasData: function( elem ) {
+               elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+
+               return !!elem && !isEmptyDataObject( elem );
+       },
+
+       data: function( elem, name, data, pvt /* Internal Use Only */ ) {
+               if ( !jQuery.acceptData( elem ) ) {
+                       return;
+               }
+
+               var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
+
+                       // We have to handle DOM nodes and JS objects differently because IE6-7
+                       // can't GC object references properly across the DOM-JS boundary
+                       isNode = elem.nodeType,
+
+                       // Only DOM nodes need the global jQuery cache; JS object data is
+                       // attached directly to the object so GC can occur automatically
+                       cache = isNode ? jQuery.cache : elem,
+
+                       // Only defining an ID for JS objects if its cache already exists allows
+                       // the code to shortcut on the same path as a DOM node with no cache
+                       id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
+
+               // Avoid doing any more work than we need to when trying to get data on an
+               // object that has no data at all
+               if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
+                       return;
+               }
+
+               if ( !id ) {
+                       // Only DOM nodes need a new unique ID for each element since their data
+                       // ends up in the global cache
+                       if ( isNode ) {
+                               elem[ jQuery.expando ] = id = ++jQuery.uuid;
+                       } else {
+                               id = jQuery.expando;
+                       }
+               }
+
+               if ( !cache[ id ] ) {
+                       cache[ id ] = {};
+
+                       // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+                       // metadata on plain JS objects when the object is serialized using
+                       // JSON.stringify
+                       if ( !isNode ) {
+                               cache[ id ].toJSON = jQuery.noop;
+                       }
+               }
+
+               // An object can be passed to jQuery.data instead of a key/value pair; this gets
+               // shallow copied over onto the existing cache
+               if ( typeof name === "object" || typeof name === "function" ) {
+                       if ( pvt ) {
+                               cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
+                       } else {
+                               cache[ id ] = jQuery.extend(cache[ id ], name);
+                       }
+               }
+
+               thisCache = cache[ id ];
+
+               // Internal jQuery data is stored in a separate object inside the object's data
+               // cache in order to avoid key collisions between internal data and user-defined
+               // data
+               if ( pvt ) {
+                       if ( !thisCache[ internalKey ] ) {
+                               thisCache[ internalKey ] = {};
+                       }
+
+                       thisCache = thisCache[ internalKey ];
+               }
+
+               if ( data !== undefined ) {
+                       thisCache[ name ] = data;
+               }
+
+               // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
+               // not attempt to inspect the internal events object using jQuery.data, as this
+               // internal data object is undocumented and subject to change.
+               if ( name === "events" && !thisCache[name] ) {
+                       return thisCache[ internalKey ] && thisCache[ internalKey ].events;
+               }
+
+               return getByName ? thisCache[ name ] : thisCache;
+       },
+
+       removeData: function( elem, name, pvt /* Internal Use Only */ ) {
+               if ( !jQuery.acceptData( elem ) ) {
+                       return;
+               }
+
+               var internalKey = jQuery.expando, isNode = elem.nodeType,
+
+                       // See jQuery.data for more information
+                       cache = isNode ? jQuery.cache : elem,
+
+                       // See jQuery.data for more information
+                       id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+               // If there is already no cache entry for this object, there is no
+               // purpose in continuing
+               if ( !cache[ id ] ) {
+                       return;
+               }
+
+               if ( name ) {
+                       var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
+
+                       if ( thisCache ) {
+                               delete thisCache[ name ];
+
+                               // If there is no data left in the cache, we want to continue
+                               // and let the cache object itself get destroyed
+                               if ( !isEmptyDataObject(thisCache) ) {
+                                       return;
+                               }
+                       }
+               }
+
+               // See jQuery.data for more information
+               if ( pvt ) {
+                       delete cache[ id ][ internalKey ];
+
+                       // Don't destroy the parent cache unless the internal data object
+                       // had been the only thing left in it
+                       if ( !isEmptyDataObject(cache[ id ]) ) {
+                               return;
+                       }
+               }
+
+               var internalCache = cache[ id ][ internalKey ];
+
+               // Browsers that fail expando deletion also refuse to delete expandos on
+               // the window, but it will allow it on all other JS objects; other browsers
+               // don't care
+               if ( jQuery.support.deleteExpando || cache != window ) {
+                       delete cache[ id ];
+               } else {
+                       cache[ id ] = null;
+               }
+
+               // We destroyed the entire user cache at once because it's faster than
+               // iterating through each key, but we need to continue to persist internal
+               // data if it existed
+               if ( internalCache ) {
+                       cache[ id ] = {};
+                       // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+                       // metadata on plain JS objects when the object is serialized using
+                       // JSON.stringify
+                       if ( !isNode ) {
+                               cache[ id ].toJSON = jQuery.noop;
+                       }
+
+                       cache[ id ][ internalKey ] = internalCache;
+
+               // Otherwise, we need to eliminate the expando on the node to avoid
+               // false lookups in the cache for entries that no longer exist
+               } else if ( isNode ) {
+                       // IE does not allow us to delete expando properties from nodes,
+                       // nor does it have a removeAttribute function on Document nodes;
+                       // we must handle all of these cases
+                       if ( jQuery.support.deleteExpando ) {
+                               delete elem[ jQuery.expando ];
+                       } else if ( elem.removeAttribute ) {
+                               elem.removeAttribute( jQuery.expando );
+                       } else {
+                               elem[ jQuery.expando ] = null;
+                       }
+               }
+       },
+
+       // For internal use only.
+       _data: function( elem, name, data ) {
+               return jQuery.data( elem, name, data, true );
+       },
+
+       // A method for determining if a DOM node can handle the data expando
+       acceptData: function( elem ) {
+               if ( elem.nodeName ) {
+                       var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+                       if ( match ) {
+                               return !(match === true || elem.getAttribute("classid") !== match);
+                       }
+               }
+
+               return true;
+       }
+});
+
+jQuery.fn.extend({
+       data: function( key, value ) {
+               var data = null;
+
+               if ( typeof key === "undefined" ) {
+                       if ( this.length ) {
+                               data = jQuery.data( this[0] );
+
+                               if ( this[0].nodeType === 1 ) {
+                           var attr = this[0].attributes, name;
+                                       for ( var i = 0, l = attr.length; i < l; i++ ) {
+                                               name = attr[i].name;
+
+                                               if ( name.indexOf( "data-" ) === 0 ) {
+                                                       name = jQuery.camelCase( name.substring(5) );
+
+                                                       dataAttr( this[0], name, data[ name ] );
+                                               }
+                                       }
+                               }
+                       }
+
+                       return data;
+
+               } else if ( typeof key === "object" ) {
+                       return this.each(function() {
+                               jQuery.data( this, key );
+                       });
+               }
+
+               var parts = key.split(".");
+               parts[1] = parts[1] ? "." + parts[1] : "";
+
+               if ( value === undefined ) {
+                       data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+                       // Try to fetch any internally stored data first
+                       if ( data === undefined && this.length ) {
+                               data = jQuery.data( this[0], key );
+                               data = dataAttr( this[0], key, data );
+                       }
+
+                       return data === undefined && parts[1] ?
+                               this.data( parts[0] ) :
+                               data;
+
+               } else {
+                       return this.each(function() {
+                               var $this = jQuery( this ),
+                                       args = [ parts[0], value ];
+
+                               $this.triggerHandler( "setData" + parts[1] + "!", args );
+                               jQuery.data( this, key, value );
+                               $this.triggerHandler( "changeData" + parts[1] + "!", args );
+                       });
+               }
+       },
+
+       removeData: function( key ) {
+               return this.each(function() {
+                       jQuery.removeData( this, key );
+               });
+       }
+});
+
+function dataAttr( elem, key, data ) {
+       // If nothing was found internally, try to fetch any
+       // data from the HTML5 data-* attribute
+       if ( data === undefined && elem.nodeType === 1 ) {
+               name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
+
+               data = elem.getAttribute( name );
+
+               if ( typeof data === "string" ) {
+                       try {
+                               data = data === "true" ? true :
+                               data === "false" ? false :
+                               data === "null" ? null :
+                               !jQuery.isNaN( data ) ? parseFloat( data ) :
+                                       rbrace.test( data ) ? jQuery.parseJSON( data ) :
+                                       data;
+                       } catch( e ) {}
+
+                       // Make sure we set the data so it isn't changed later
+                       jQuery.data( elem, key, data );
+
+               } else {
+                       data = undefined;
+               }
+       }
+
+       return data;
+}
+
+// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
+// property to be considered empty objects; this property always exists in
+// order to make sure JSON.stringify does not expose internal metadata
+function isEmptyDataObject( obj ) {
+       for ( var name in obj ) {
+               if ( name !== "toJSON" ) {
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+
+
+
+function handleQueueMarkDefer( elem, type, src ) {
+       var deferDataKey = type + "defer",
+               queueDataKey = type + "queue",
+               markDataKey = type + "mark",
+               defer = jQuery.data( elem, deferDataKey, undefined, true );
+       if ( defer &&
+               ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
+               ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
+               // Give room for hard-coded callbacks to fire first
+               // and eventually mark/queue something else on the element
+               setTimeout( function() {
+                       if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
+                               !jQuery.data( elem, markDataKey, undefined, true ) ) {
+                               jQuery.removeData( elem, deferDataKey, true );
+                               defer.resolve();
+                       }
+               }, 0 );
+       }
+}
+
+jQuery.extend({
+
+       _mark: function( elem, type ) {
+               if ( elem ) {
+                       type = (type || "fx") + "mark";
+                       jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
+               }
+       },
+
+       _unmark: function( force, elem, type ) {
+               if ( force !== true ) {
+                       type = elem;
+                       elem = force;
+                       force = false;
+               }
+               if ( elem ) {
+                       type = type || "fx";
+                       var key = type + "mark",
+                               count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
+                       if ( count ) {
+                               jQuery.data( elem, key, count, true );
+                       } else {
+                               jQuery.removeData( elem, key, true );
+                               handleQueueMarkDefer( elem, type, "mark" );
+                       }
+               }
+       },
+
+       queue: function( elem, type, data ) {
+               if ( elem ) {
+                       type = (type || "fx") + "queue";
+                       var q = jQuery.data( elem, type, undefined, true );
+                       // Speed up dequeue by getting out quickly if this is just a lookup
+                       if ( data ) {
+                               if ( !q || jQuery.isArray(data) ) {
+                                       q = jQuery.data( elem, type, jQuery.makeArray(data), true );
+                               } else {
+                                       q.push( data );
+                               }
+                       }
+                       return q || [];
+               }
+       },
+
+       dequeue: function( elem, type ) {
+               type = type || "fx";
+
+               var queue = jQuery.queue( elem, type ),
+                       fn = queue.shift(),
+                       defer;
+
+               // If the fx queue is dequeued, always remove the progress sentinel
+               if ( fn === "inprogress" ) {
+                       fn = queue.shift();
+               }
+
+               if ( fn ) {
+                       // Add a progress sentinel to prevent the fx queue from being
+                       // automatically dequeued
+                       if ( type === "fx" ) {
+                               queue.unshift("inprogress");
+                       }
+
+                       fn.call(elem, function() {
+                               jQuery.dequeue(elem, type);
+                       });
+               }
+
+               if ( !queue.length ) {
+                       jQuery.removeData( elem, type + "queue", true );
+                       handleQueueMarkDefer( elem, type, "queue" );
+               }
+       }
+});
+
+jQuery.fn.extend({
+       queue: function( type, data ) {
+               if ( typeof type !== "string" ) {
+                       data = type;
+                       type = "fx";
+               }
+
+               if ( data === undefined ) {
+                       return jQuery.queue( this[0], type );
+               }
+               return this.each(function() {
+                       var queue = jQuery.queue( this, type, data );
+
+                       if ( type === "fx" && queue[0] !== "inprogress" ) {
+                               jQuery.dequeue( this, type );
+                       }
+               });
+       },
+       dequeue: function( type ) {
+               return this.each(function() {
+                       jQuery.dequeue( this, type );
+               });
+       },
+       // Based off of the plugin by Clint Helfers, with permission.
+       // http://blindsignals.com/index.php/2009/07/jquery-delay/
+       delay: function( time, type ) {
+               time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+               type = type || "fx";
+
+               return this.queue( type, function() {
+                       var elem = this;
+                       setTimeout(function() {
+                               jQuery.dequeue( elem, type );
+                       }, time );
+               });
+       },
+       clearQueue: function( type ) {
+               return this.queue( type || "fx", [] );
+       },
+       // Get a promise resolved when queues of a certain type
+       // are emptied (fx is the type by default)
+       promise: function( type, object ) {
+               if ( typeof type !== "string" ) {
+                       object = type;
+                       type = undefined;
+               }
+               type = type || "fx";
+               var defer = jQuery.Deferred(),
+                       elements = this,
+                       i = elements.length,
+                       count = 1,
+                       deferDataKey = type + "defer",
+                       queueDataKey = type + "queue",
+                       markDataKey = type + "mark";
+               function resolve() {
+                       if ( !( --count ) ) {
+                               defer.resolveWith( elements, [ elements ] );
+                       }
+               }
+               while( i-- ) {
+                       if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
+                                       ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
+                                               jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
+                                       jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
+                               count++;
+                               tmp.done( resolve );
+                       }
+               }
+               resolve();
+               return defer.promise();
+       }
+});
+
+
+
+
+var rclass = /[\n\t\r]/g,
+       rspace = /\s+/,
+       rreturn = /\r/g,
+       rtype = /^(?:button|input)$/i,
+       rfocusable = /^(?:button|input|object|select|textarea)$/i,
+       rclickable = /^a(?:rea)?$/i,
+       rspecial = /^(?:data-|aria-)/,
+       rinvalidChar = /\:/,
+       formHook;
+
+jQuery.fn.extend({
+       attr: function( name, value ) {
+               return jQuery.access( this, name, value, true, jQuery.attr );
+       },
+
+       removeAttr: function( name ) {
+               return this.each(function() {
+                       jQuery.removeAttr( this, name );
+               });
+       },
+       
+       prop: function( name, value ) {
+               return jQuery.access( this, name, value, true, jQuery.prop );
+       },
+       
+       removeProp: function( name ) {
+               return this.each(function() {
+                       // try/catch handles cases where IE balks (such as removing a property on window)
+                       try {
+                               this[ name ] = undefined;
+                               delete this[ name ];
+                       } catch( e ) {}
+               });
+       },
+
+       addClass: function( value ) {
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function(i) {
+                               var self = jQuery(this);
+                               self.addClass( value.call(this, i, self.attr("class") || "") );
+                       });
+               }
+
+               if ( value && typeof value === "string" ) {
+                       var classNames = (value || "").split( rspace );
+
+                       for ( var i = 0, l = this.length; i < l; i++ ) {
+                               var elem = this[i];
+
+                               if ( elem.nodeType === 1 ) {
+                                       if ( !elem.className ) {
+                                               elem.className = value;
+
+                                       } else {
+                                               var className = " " + elem.className + " ",
+                                                       setClass = elem.className;
+
+                                               for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+                                                       if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+                                                               setClass += " " + classNames[c];
+                                                       }
+                                               }
+                                               elem.className = jQuery.trim( setClass );
+                                       }
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       removeClass: function( value ) {
+               if ( jQuery.isFunction(value) ) {
+                       return this.each(function(i) {
+                               var self = jQuery(this);
+                               self.removeClass( value.call(this, i, self.attr("class")) );
+                       });
+               }
+
+               if ( (value && typeof value === "string") || value === undefined ) {
+                       var classNames = (value || "").split( rspace );
+
+                       for ( var i = 0, l = this.length; i < l; i++ ) {
+                               var elem = this[i];
+
+                               if ( elem.nodeType === 1 && elem.className ) {
+                                       if ( value ) {
+                                               var className = (" " + elem.className + " ").replace(rclass, " ");
+                                               for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+                                                       className = className.replace(" " + classNames[c] + " ", " ");
+                                               }
+                                               elem.className = jQuery.trim( className );
+
+                                       } else {
+                                               elem.className = "";
+                                       }
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       toggleClass: function( value, stateVal ) {
+               var type = typeof value,
+                       isBool = typeof stateVal === "boolean";
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function(i) {
+                               var self = jQuery(this);
+                               self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+                       });
+               }
+
+               return this.each(function() {
+                       if ( type === "string" ) {
+                               // toggle individual class names
+                               var className,
+                                       i = 0,
+                                       self = jQuery( this ),
+                                       state = stateVal,
+                                       classNames = value.split( rspace );
+
+                               while ( (className = classNames[ i++ ]) ) {
+                                       // check each className given, space seperated list
+                                       state = isBool ? state : !self.hasClass( className );
+                                       self[ state ? "addClass" : "removeClass" ]( className );
+                               }
+
+                       } else if ( type === "undefined" || type === "boolean" ) {
+                               if ( this.className ) {
+                                       // store className if set
+                                       jQuery._data( this, "__className__", this.className );
+                               }
+
+                               // toggle whole className
+                               this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+                       }
+               });
+       },
+
+       hasClass: function( selector ) {
+               var className = " " + selector + " ";
+               for ( var i = 0, l = this.length; i < l; i++ ) {
+                       if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       },
+
+       val: function( value ) {
+               var hooks, ret,
+                       elem = this[0];
+               
+               if ( !arguments.length ) {
+                       if ( elem ) {
+                               hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
+
+                               if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+                                       return ret;
+                               }
+
+                               return (elem.value || "").replace(rreturn, "");
+                       }
+
+                       return undefined;
+               }
+
+               var isFunction = jQuery.isFunction( value );
+
+               return this.each(function( i ) {
+                       var self = jQuery(this), val;
+
+                       if ( this.nodeType !== 1 ) {
+                               return;
+                       }
+
+                       if ( isFunction ) {
+                               val = value.call( this, i, self.val() );
+                       } else {
+                               val = value;
+                       }
+
+                       // Treat null/undefined as ""; convert numbers to string
+                       if ( val == null ) {
+                               val = "";
+                       } else if ( typeof val === "number" ) {
+                               val += "";
+                       } else if ( jQuery.isArray( val ) ) {
+                               val = jQuery.map(val, function ( value ) {
+                                       return value == null ? "" : value + "";
+                               });
+                       }
+
+                       hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
+
+                       // If set returns undefined, fall back to normal setting
+                       if ( !hooks || ("set" in hooks && hooks.set( this, val, "value" ) === undefined) ) {
+                               this.value = val;
+                       }
+               });
+       }
+});
+
+jQuery.extend({
+       valHooks: {
+               option: {
+                       get: function( elem ) {
+                               // attributes.value is undefined in Blackberry 4.7 but
+                               // uses .value. See #6932
+                               var val = elem.attributes.value;
+                               return !val || val.specified ? elem.value : elem.text;
+                       }
+               },
+               select: {
+                       get: function( elem ) {
+                               var index = elem.selectedIndex,
+                                       values = [],
+                                       options = elem.options,
+                                       one = elem.type === "select-one";
+
+                               // Nothing was selected
+                               if ( index < 0 ) {
+                                       return null;
+                               }
+
+                               // Loop through all the selected options
+                               for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+                                       var option = options[ i ];
+
+                                       // Don't return options that are disabled or in a disabled optgroup
+                                       if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
+                                                       (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
+
+                                               // Get the specific value for the option
+                                               value = jQuery( option ).val();
+
+                                               // We don't need an array for one selects
+                                               if ( one ) {
+                                                       return value;
+                                               }
+
+                                               // Multi-Selects return an array
+                                               values.push( value );
+                                       }
+                               }
+
+                               // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
+                               if ( one && !values.length && options.length ) {
+                                       return jQuery( options[ index ] ).val();
+                               }
+
+                               return values;
+                       },
+
+                       set: function( elem, value ) {
+                               var values = jQuery.makeArray( value );
+
+                               jQuery(elem).find("option").each(function() {
+                                       this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+                               });
+
+                               if ( !values.length ) {
+                                       elem.selectedIndex = -1;
+                               }
+                               return values;
+                       }
+               }
+       },
+
+       attrFn: {
+               val: true,
+               css: true,
+               html: true,
+               text: true,
+               data: true,
+               width: true,
+               height: true,
+               offset: true
+       },
+       
+       attrFix: {
+               // Always normalize to ensure hook usage
+               tabindex: "tabIndex",
+               readonly: "readOnly"
+       },
+       
+       attr: function( elem, name, value, pass ) {
+               var nType = elem.nodeType;
+               
+               // don't get/set attributes on text, comment and attribute nodes
+               if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+                       return undefined;
+               }
+
+               if ( pass && name in jQuery.attrFn ) {
+                       return jQuery( elem )[ name ]( value );
+               }
+               
+               var ret, hooks,
+                       notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+               
+               // Normalize the name if needed
+               name = notxml && jQuery.attrFix[ name ] || name;
+
+               // Get the appropriate hook, or the formHook
+               // if getSetAttribute is not supported and we have form objects in IE6/7
+               hooks = jQuery.attrHooks[ name ] ||
+                       ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ?
+                               formHook :
+                               undefined );
+
+               if ( value !== undefined ) {
+
+                       if ( value === null || (value === false && !rspecial.test( name )) ) {
+                               jQuery.removeAttr( elem, name );
+                               return undefined;
+
+                       } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
+                               return ret;
+
+                       } else {
+
+                               // Set boolean attributes to the same name
+                               if ( value === true && !rspecial.test( name ) ) {
+                                       value = name;
+                               }
+
+                               elem.setAttribute( name, "" + value );
+                               return value;
+                       }
+
+               } else {
+
+                       if ( hooks && "get" in hooks && notxml ) {
+                               return hooks.get( elem, name );
+
+                       } else {
+
+                               ret = elem.getAttribute( name );
+
+                               // Non-existent attributes return null, we normalize to undefined
+                               return ret === null ?
+                                       undefined :
+                                       ret;
+                       }
+               }
+       },
+       
+       removeAttr: function( elem, name ) {
+               if ( elem.nodeType === 1 ) {
+                       name = jQuery.attrFix[ name ] || name;
+               
+                       if ( jQuery.support.getSetAttribute ) {
+                               // Use removeAttribute in browsers that support it
+                               elem.removeAttribute( name );
+                       } else {
+                               jQuery.attr( elem, name, "" );
+                               elem.removeAttributeNode( elem.getAttributeNode( name ) );
+                       }
+               }
+       },
+
+       attrHooks: {
+               type: {
+                       set: function( elem, value ) {
+                               // We can't allow the type property to be changed (since it causes problems in IE)
+                               if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
+                                       jQuery.error( "type property can't be changed" );
+                               } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+                                       // Setting the type on a radio button after the value resets the value in IE6-9
+                                       // Reset value to it's default in case type is set after value
+                                       // This is for element creation
+                                       var val = elem.getAttribute("value");
+                                       elem.setAttribute( "type", value );
+                                       if ( val ) {
+                                               elem.value = val;
+                                       }
+                                       return value;
+                               }
+                       }
+               },
+               tabIndex: {
+                       get: function( elem ) {
+                               // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+                               // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+                               var attributeNode = elem.getAttributeNode("tabIndex");
+
+                               return attributeNode && attributeNode.specified ?
+                                       parseInt( attributeNode.value, 10 ) :
+                                       rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+                                               0 :
+                                               undefined;
+                       }
+               }
+       },
+       
+       propFix: {},
+       
+       prop: function( elem, name, value ) {
+               var nType = elem.nodeType;
+               
+               // don't get/set properties on text, comment and attribute nodes
+               if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+                       return undefined;
+               }
+               
+               var ret, hooks,
+                       notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+               
+               // Try to normalize/fix the name
+               name = notxml && jQuery.propFix[ name ] || name;
+               
+               hooks = jQuery.propHooks[ name ];
+               
+               if ( value !== undefined ) {
+                       if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+                               return ret;
+                       
+                       } else {
+                               return (elem[ name ] = value);
+                       }
+               
+               } else {
+                       if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
+                               return ret;
+                               
+                       } else {
+                               return elem[ name ];
+                       }
+               }
+       },
+       
+       propHooks: {}
+});
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !jQuery.support.getSetAttribute ) {
+       jQuery.attrFix = jQuery.extend( jQuery.attrFix, {
+               "for": "htmlFor",
+               "class": "className",
+               maxlength: "maxLength",
+               cellspacing: "cellSpacing",
+               cellpadding: "cellPadding",
+               rowspan: "rowSpan",
+               colspan: "colSpan",
+               usemap: "useMap",
+               frameborder: "frameBorder"
+       });
+       
+       // Use this for any attribute on a form in IE6/7
+       formHook = jQuery.attrHooks.name = jQuery.attrHooks.value = jQuery.valHooks.button = {
+               get: function( elem, name ) {
+                       var ret;
+                       if ( name === "value" && !jQuery.nodeName( elem, "button" ) ) {
+                               return elem.getAttribute( name );
+                       }
+                       ret = elem.getAttributeNode( name );
+                       // Return undefined if not specified instead of empty string
+                       return ret && ret.specified ?
+                               ret.nodeValue :
+                               undefined;
+               },
+               set: function( elem, value, name ) {
+                       // Check form objects in IE (multiple bugs related)
+                       // Only use nodeValue if the attribute node exists on the form
+                       var ret = elem.getAttributeNode( name );
+                       if ( ret ) {
+                               ret.nodeValue = value;
+                               return value;
+                       }
+               }
+       };
+
+       // Set width and height to auto instead of 0 on empty string( Bug #8150 )
+       // This is for removals
+       jQuery.each([ "width", "height" ], function( i, name ) {
+               jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+                       set: function( elem, value ) {
+                               if ( value === "" ) {
+                                       elem.setAttribute( name, "auto" );
+                                       return value;
+                               }
+                       }
+               });
+       });
+}
+
+
+// Some attributes require a special call on IE
+if ( !jQuery.support.hrefNormalized ) {
+       jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
+               jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+                       get: function( elem ) {
+                               var ret = elem.getAttribute( name, 2 );
+                               return ret === null ? undefined : ret;
+                       }
+               });
+       });
+}
+
+if ( !jQuery.support.style ) {
+       jQuery.attrHooks.style = {
+               get: function( elem ) {
+                       // Return undefined in the case of empty string
+                       // Normalize to lowercase since IE uppercases css property names
+                       return elem.style.cssText.toLowerCase() || undefined;
+               },
+               set: function( elem, value ) {
+                       return (elem.style.cssText = "" + value);
+               }
+       };
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+       jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
+               get: function( elem ) {
+                       var parent = elem.parentNode;
+
+                       if ( parent ) {
+                               parent.selectedIndex;
+
+                               // Make sure that it also works with optgroups, see #5701
+                               if ( parent.parentNode ) {
+                                       parent.parentNode.selectedIndex;
+                               }
+                       }
+               }
+       });
+}
+
+// Radios and checkboxes getter/setter
+if ( !jQuery.support.checkOn ) {
+       jQuery.each([ "radio", "checkbox" ], function() {
+               jQuery.valHooks[ this ] = {
+                       get: function( elem ) {
+                               // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+                               return elem.getAttribute("value") === null ? "on" : elem.value;
+                       }
+               };
+       });
+}
+jQuery.each([ "radio", "checkbox" ], function() {
+       jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
+               set: function( elem, value ) {
+                       if ( jQuery.isArray( value ) ) {
+                               return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
+                       }
+               }
+       });
+});
+
+
+
+
+var hasOwn = Object.prototype.hasOwnProperty,
+       rnamespaces = /\.(.*)$/,
+       rformElems = /^(?:textarea|input|select)$/i,
+       rperiod = /\./g,
+       rspaces = / /g,
+       rescape = /[^\w\s.|`]/g,
+       fcleanup = function( nm ) {
+               return nm.replace(rescape, "\\$&");
+       };
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+       // Bind an event to an element
+       // Original by Dean Edwards
+       add: function( elem, types, handler, data ) {
+               if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+                       return;
+               }
+
+               if ( handler === false ) {
+                       handler = returnFalse;
+               } else if ( !handler ) {
+                       // Fixes bug #7229. Fix recommended by jdalton
+                       return;
+               }
+
+               var handleObjIn, handleObj;
+
+               if ( handler.handler ) {
+                       handleObjIn = handler;
+                       handler = handleObjIn.handler;
+               }
+
+               // Make sure that the function being executed has a unique ID
+               if ( !handler.guid ) {
+                       handler.guid = jQuery.guid++;
+               }
+
+               // Init the element's event structure
+               var elemData = jQuery._data( elem );
+
+               // If no elemData is found then we must be trying to bind to one of the
+               // banned noData elements
+               if ( !elemData ) {
+                       return;
+               }
+
+               var events = elemData.events,
+                       eventHandle = elemData.handle;
+
+               if ( !events ) {
+                       elemData.events = events = {};
+               }
+
+               if ( !eventHandle ) {
+                       elemData.handle = eventHandle = function( e ) {
+                               // Discard the second event of a jQuery.event.trigger() and
+                               // when an event is called after a page has unloaded
+                               return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
+                                       jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+                                       undefined;
+                       };
+               }
+
+               // Add elem as a property of the handle function
+               // This is to prevent a memory leak with non-native events in IE.
+               eventHandle.elem = elem;
+
+               // Handle multiple events separated by a space
+               // jQuery(...).bind("mouseover mouseout", fn);
+               types = types.split(" ");
+
+               var type, i = 0, namespaces;
+
+               while ( (type = types[ i++ ]) ) {
+                       handleObj = handleObjIn ?
+                               jQuery.extend({}, handleObjIn) :
+                               { handler: handler, data: data };
+
+                       // Namespaced event handlers
+                       if ( type.indexOf(".") > -1 ) {
+                               namespaces = type.split(".");
+                               type = namespaces.shift();
+                               handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+                       } else {
+                               namespaces = [];
+                               handleObj.namespace = "";
+                       }
+
+                       handleObj.type = type;
+                       if ( !handleObj.guid ) {
+                               handleObj.guid = handler.guid;
+                       }
+
+                       // Get the current list of functions bound to this event
+                       var handlers = events[ type ],
+                               special = jQuery.event.special[ type ] || {};
+
+                       // Init the event handler queue
+                       if ( !handlers ) {
+                               handlers = events[ type ] = [];
+
+                               // Check for a special event handler
+                               // Only use addEventListener/attachEvent if the special
+                               // events handler returns false
+                               if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+                                       // Bind the global event handler to the element
+                                       if ( elem.addEventListener ) {
+                                               elem.addEventListener( type, eventHandle, false );
+
+                                       } else if ( elem.attachEvent ) {
+                                               elem.attachEvent( "on" + type, eventHandle );
+                                       }
+                               }
+                       }
+
+                       if ( special.add ) {
+                               special.add.call( elem, handleObj );
+
+                               if ( !handleObj.handler.guid ) {
+                                       handleObj.handler.guid = handler.guid;
+                               }
+                       }
+
+                       // Add the function to the element's handler list
+                       handlers.push( handleObj );
+
+                       // Keep track of which events have been used, for event optimization
+                       jQuery.event.global[ type ] = true;
+               }
+
+               // Nullify elem to prevent memory leaks in IE
+               elem = null;
+       },
+
+       global: {},
+
+       // Detach an event or set of events from an element
+       remove: function( elem, types, handler, pos ) {
+               // don't do events on text and comment nodes
+               if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+                       return;
+               }
+
+               if ( handler === false ) {
+                       handler = returnFalse;
+               }
+
+               var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+                       elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
+                       events = elemData && elemData.events;
+
+               if ( !elemData || !events ) {
+                       return;
+               }
+
+               // types is actually an event object here
+               if ( types && types.type ) {
+                       handler = types.handler;
+                       types = types.type;
+               }
+
+               // Unbind all events for the element
+               if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+                       types = types || "";
+
+                       for ( type in events ) {
+                               jQuery.event.remove( elem, type + types );
+                       }
+
+                       return;
+               }
+
+               // Handle multiple events separated by a space
+               // jQuery(...).unbind("mouseover mouseout", fn);
+               types = types.split(" ");
+
+               while ( (type = types[ i++ ]) ) {
+                       origType = type;
+                       handleObj = null;
+                       all = type.indexOf(".") < 0;
+                       namespaces = [];
+
+                       if ( !all ) {
+                               // Namespaced event handlers
+                               namespaces = type.split(".");
+                               type = namespaces.shift();
+
+                               namespace = new RegExp("(^|\\.)" +
+                                       jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
+                       }
+
+                       eventType = events[ type ];
+
+                       if ( !eventType ) {
+                               continue;
+                       }
+
+                       if ( !handler ) {
+                               for ( j = 0; j < eventType.length; j++ ) {
+                                       handleObj = eventType[ j ];
+
+                                       if ( all || namespace.test( handleObj.namespace ) ) {
+                                               jQuery.event.remove( elem, origType, handleObj.handler, j );
+                                               eventType.splice( j--, 1 );
+                                       }
+                               }
+
+                               continue;
+                       }
+
+                       special = jQuery.event.special[ type ] || {};
+
+                       for ( j = pos || 0; j < eventType.length; j++ ) {
+                               handleObj = eventType[ j ];
+
+                               if ( handler.guid === handleObj.guid ) {
+                                       // remove the given handler for the given type
+                                       if ( all || namespace.test( handleObj.namespace ) ) {
+                                               if ( pos == null ) {
+                                                       eventType.splice( j--, 1 );
+                                               }
+
+                                               if ( special.remove ) {
+                                                       special.remove.call( elem, handleObj );
+                                               }
+                                       }
+
+                                       if ( pos != null ) {
+                                               break;
+                                       }
+                               }
+                       }
+
+                       // remove generic event handler if no more handlers exist
+                       if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+                               if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+                                       jQuery.removeEvent( elem, type, elemData.handle );
+                               }
+
+                               ret = null;
+                               delete events[ type ];
+                       }
+               }
+
+               // Remove the expando if it's no longer used
+               if ( jQuery.isEmptyObject( events ) ) {
+                       var handle = elemData.handle;
+                       if ( handle ) {
+                               handle.elem = null;
+                       }
+
+                       delete elemData.events;
+                       delete elemData.handle;
+
+                       if ( jQuery.isEmptyObject( elemData ) ) {
+                               jQuery.removeData( elem, undefined, true );
+                       }
+               }
+       },
+       
+       // Events that are safe to short-circuit if no handlers are attached.
+       // Native DOM events should not be added, they may have inline handlers.
+       customEvent: {
+               "getData": true,
+               "setData": true,
+               "changeData": true
+       },
+
+       trigger: function( event, data, elem, onlyHandlers ) {
+               // Event object or event type
+               var type = event.type || event,
+                       namespaces = [],
+                       exclusive;
+
+               if ( type.indexOf("!") >= 0 ) {
+                       // Exclusive events trigger only for the exact event (no namespaces)
+                       type = type.slice(0, -1);
+                       exclusive = true;
+               }
+
+               if ( type.indexOf(".") >= 0 ) {
+                       // Namespaced trigger; create a regexp to match event type in handle()
+                       namespaces = type.split(".");
+                       type = namespaces.shift();
+                       namespaces.sort();
+               }
+
+               if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
+                       // No jQuery handlers for this event type, and it can't have inline handlers
+                       return;
+               }
+
+               // Caller can pass in an Event, Object, or just an event type string
+               event = typeof event === "object" ?
+                       // jQuery.Event object
+                       event[ jQuery.expando ] ? event :
+                       // Object literal
+                       new jQuery.Event( type, event ) :
+                       // Just the event type (string)
+                       new jQuery.Event( type );
+
+               event.type = type;
+               event.exclusive = exclusive;
+               event.namespace = namespaces.join(".");
+               event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
+               
+               // triggerHandler() and global events don't bubble or run the default action
+               if ( onlyHandlers || !elem ) {
+                       event.preventDefault();
+                       event.stopPropagation();
+               }
+
+               // Handle a global trigger
+               if ( !elem ) {
+                       // TODO: Stop taunting the data cache; remove global events and always attach to document
+                       jQuery.each( jQuery.cache, function() {
+                               // internalKey variable is just used to make it easier to find
+                               // and potentially change this stuff later; currently it just
+                               // points to jQuery.expando
+                               var internalKey = jQuery.expando,
+                                       internalCache = this[ internalKey ];
+                               if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
+                                       jQuery.event.trigger( event, data, internalCache.handle.elem );
+                               }
+                       });
+                       return;
+               }
+
+               // Don't do events on text and comment nodes
+               if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+                       return;
+               }
+
+               // Clean up the event in case it is being reused
+               event.result = undefined;
+               event.target = elem;
+
+               // Clone any incoming data and prepend the event, creating the handler arg list
+               data = data ? jQuery.makeArray( data ) : [];
+               data.unshift( event );
+
+               var cur = elem,
+                       // IE doesn't like method names with a colon (#3533, #8272)
+                       ontype = type.indexOf(":") < 0 ? "on" + type : "";
+
+               // Fire event on the current element, then bubble up the DOM tree
+               do {
+                       var handle = jQuery._data( cur, "handle" );
+
+                       event.currentTarget = cur;
+                       if ( handle ) {
+                               handle.apply( cur, data );
+                       }
+
+                       // Trigger an inline bound script
+                       if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
+                               event.result = false;
+                               event.preventDefault();
+                       }
+
+                       // Bubble up to document, then to window
+                       cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
+               } while ( cur && !event.isPropagationStopped() );
+
+               // If nobody prevented the default action, do it now
+               if ( !event.isDefaultPrevented() ) {
+                       var old,
+                               special = jQuery.event.special[ type ] || {};
+
+                       if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
+                               !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
+
+                               // Call a native DOM method on the target with the same name name as the event.
+                               // Can't use an .isFunction)() check here because IE6/7 fails that test.
+                               // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
+                               try {
+                                       if ( ontype && elem[ type ] ) {
+                                               // Don't re-trigger an onFOO event when we call its FOO() method
+                                               old = elem[ ontype ];
+
+                                               if ( old ) {
+                                                       elem[ ontype ] = null;
+                                               }
+
+                                               jQuery.event.triggered = type;
+                                               elem[ type ]();
+                                       }
+                               } catch ( ieError ) {}
+
+                               if ( old ) {
+                                       elem[ ontype ] = old;
+                               }
+
+                               jQuery.event.triggered = undefined;
+                       }
+               }
+               
+               return event.result;
+       },
+
+       handle: function( event ) {
+               event = jQuery.event.fix( event || window.event );
+               // Snapshot the handlers list since a called handler may add/remove events.
+               var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
+                       run_all = !event.exclusive && !event.namespace,
+                       args = Array.prototype.slice.call( arguments, 0 );
+
+               // Use the fix-ed Event rather than the (read-only) native event
+               args[0] = event;
+               event.currentTarget = this;
+
+               for ( var j = 0, l = handlers.length; j < l; j++ ) {
+                       var handleObj = handlers[ j ];
+
+                       // Triggered event must 1) be non-exclusive and have no namespace, or
+                       // 2) have namespace(s) a subset or equal to those in the bound event.
+                       if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
+                               // Pass in a reference to the handler function itself
+                               // So that we can later remove it
+                               event.handler = handleObj.handler;
+                               event.data = handleObj.data;
+                               event.handleObj = handleObj;
+
+                               var ret = handleObj.handler.apply( this, args );
+
+                               if ( ret !== undefined ) {
+                                       event.result = ret;
+                                       if ( ret === false ) {
+                                               event.preventDefault();
+                                               event.stopPropagation();
+                                       }
+                               }
+
+                               if ( event.isImmediatePropagationStopped() ) {
+                                       break;
+                               }
+                       }
+               }
+               return event.result;
+       },
+
+       props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+       fix: function( event ) {
+               if ( event[ jQuery.expando ] ) {
+                       return event;
+               }
+
+               // store a copy of the original event object
+               // and "clone" to set read-only properties
+               var originalEvent = event;
+               event = jQuery.Event( originalEvent );
+
+               for ( var i = this.props.length, prop; i; ) {
+                       prop = this.props[ --i ];
+                       event[ prop ] = originalEvent[ prop ];
+               }
+
+               // Fix target property, if necessary
+               if ( !event.target ) {
+                       // Fixes #1925 where srcElement might not be defined either
+                       event.target = event.srcElement || document;
+               }
+
+               // check if target is a textnode (safari)
+               if ( event.target.nodeType === 3 ) {
+                       event.target = event.target.parentNode;
+               }
+
+               // Add relatedTarget, if necessary
+               if ( !event.relatedTarget && event.fromElement ) {
+                       event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+               }
+
+               // Calculate pageX/Y if missing and clientX/Y available
+               if ( event.pageX == null && event.clientX != null ) {
+                       var eventDocument = event.target.ownerDocument || document,
+                               doc = eventDocument.documentElement,
+                               body = eventDocument.body;
+
+                       event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+                       event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
+               }
+
+               // Add which for key events
+               if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
+                       event.which = event.charCode != null ? event.charCode : event.keyCode;
+               }
+
+               // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+               if ( !event.metaKey && event.ctrlKey ) {
+                       event.metaKey = event.ctrlKey;
+               }
+
+               // Add which for click: 1 === left; 2 === middle; 3 === right
+               // Note: button is not normalized, so don't use it
+               if ( !event.which && event.button !== undefined ) {
+                       event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+               }
+
+               return event;
+       },
+
+       // Deprecated, use jQuery.guid instead
+       guid: 1E8,
+
+       // Deprecated, use jQuery.proxy instead
+       proxy: jQuery.proxy,
+
+       special: {
+               ready: {
+                       // Make sure the ready event is setup
+                       setup: jQuery.bindReady,
+                       teardown: jQuery.noop
+               },
+
+               live: {
+                       add: function( handleObj ) {
+                               jQuery.event.add( this,
+                                       liveConvert( handleObj.origType, handleObj.selector ),
+                                       jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
+                       },
+
+                       remove: function( handleObj ) {
+                               jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
+                       }
+               },
+
+               beforeunload: {
+                       setup: function( data, namespaces, eventHandle ) {
+                               // We only want to do this special case on windows
+                               if ( jQuery.isWindow( this ) ) {
+                                       this.onbeforeunload = eventHandle;
+                               }
+                       },
+
+                       teardown: function( namespaces, eventHandle ) {
+                               if ( this.onbeforeunload === eventHandle ) {
+                                       this.onbeforeunload = null;
+                               }
+                       }
+               }
+       }
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+       function( elem, type, handle ) {
+               if ( elem.removeEventListener ) {
+                       elem.removeEventListener( type, handle, false );
+               }
+       } :
+       function( elem, type, handle ) {
+               if ( elem.detachEvent ) {
+                       elem.detachEvent( "on" + type, handle );
+               }
+       };
+
+jQuery.Event = function( src, props ) {
+       // Allow instantiation without the 'new' keyword
+       if ( !this.preventDefault ) {
+               return new jQuery.Event( src, props );
+       }
+
+       // Event object
+       if ( src && src.type ) {
+               this.originalEvent = src;
+               this.type = src.type;
+
+               // Events bubbling up the document may have been marked as prevented
+               // by a handler lower down the tree; reflect the correct value.
+               this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
+                       src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
+
+       // Event type
+       } else {
+               this.type = src;
+       }
+
+       // Put explicitly provided properties onto the event object
+       if ( props ) {
+               jQuery.extend( this, props );
+       }
+
+       // timeStamp is buggy for some events on Firefox(#3843)
+       // So we won't rely on the native value
+       this.timeStamp = jQuery.now();
+
+       // Mark it as fixed
+       this[ jQuery.expando ] = true;
+};
+
+function returnFalse() {
+       return false;
+}
+function returnTrue() {
+       return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+       preventDefault: function() {
+               this.isDefaultPrevented = returnTrue;
+
+               var e = this.originalEvent;
+               if ( !e ) {
+                       return;
+               }
+
+               // if preventDefault exists run it on the original event
+               if ( e.preventDefault ) {
+                       e.preventDefault();
+
+               // otherwise set the returnValue property of the original event to false (IE)
+               } else {
+                       e.returnValue = false;
+               }
+       },
+       stopPropagation: function() {
+               this.isPropagationStopped = returnTrue;
+
+               var e = this.originalEvent;
+               if ( !e ) {
+                       return;
+               }
+               // if stopPropagation exists run it on the original event
+               if ( e.stopPropagation ) {
+                       e.stopPropagation();
+               }
+               // otherwise set the cancelBubble property of the original event to true (IE)
+               e.cancelBubble = true;
+       },
+       stopImmediatePropagation: function() {
+               this.isImmediatePropagationStopped = returnTrue;
+               this.stopPropagation();
+       },
+       isDefaultPrevented: returnFalse,
+       isPropagationStopped: returnFalse,
+       isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+       // Check if mouse(over|out) are still within the same parent element
+       var parent = event.relatedTarget;
+
+       // Firefox sometimes assigns relatedTarget a XUL element
+       // which we cannot access the parentNode property of
+       try {
+
+               // Chrome does something similar, the parentNode property
+               // can be accessed but is null.
+               if ( parent && parent !== document && !parent.parentNode ) {
+                       return;
+               }
+               // Traverse up the tree
+               while ( parent && parent !== this ) {
+                       parent = parent.parentNode;
+               }
+
+               if ( parent !== this ) {
+                       // set the correct event type
+                       event.type = event.data;
+
+                       // handle event if we actually just moused on to a non sub-element
+                       jQuery.event.handle.apply( this, arguments );
+               }
+
+       // assuming we've left the element since we most likely mousedover a xul element
+       } catch(e) { }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+       event.type = event.data;
+       jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+       mouseenter: "mouseover",
+       mouseleave: "mouseout"
+}, function( orig, fix ) {
+       jQuery.event.special[ orig ] = {
+               setup: function( data ) {
+                       jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+               },
+               teardown: function( data ) {
+                       jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+               }
+       };
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+       jQuery.event.special.submit = {
+               setup: function( data, namespaces ) {
+                       if ( !jQuery.nodeName( this, "form" ) ) {
+                               jQuery.event.add(this, "click.specialSubmit", function( e ) {
+                                       var elem = e.target,
+                                               type = elem.type;
+
+                                       if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+                                               trigger( "submit", this, arguments );
+                                       }
+                               });
+
+                               jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
+                                       var elem = e.target,
+                                               type = elem.type;
+
+                                       if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+                                               trigger( "submit", this, arguments );
+                                       }
+                               });
+
+                       } else {
+                               return false;
+                       }
+               },
+
+               teardown: function( namespaces ) {
+                       jQuery.event.remove( this, ".specialSubmit" );
+               }
+       };
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+       var changeFilters,
+
+       getVal = function( elem ) {
+               var type = elem.type, val = elem.value;
+
+               if ( type === "radio" || type === "checkbox" ) {
+                       val = elem.checked;
+
+               } else if ( type === "select-multiple" ) {
+                       val = elem.selectedIndex > -1 ?
+                               jQuery.map( elem.options, function( elem ) {
+                                       return elem.selected;
+                               }).join("-") :
+                               "";
+
+               } else if ( jQuery.nodeName( elem, "select" ) ) {
+                       val = elem.selectedIndex;
+               }
+
+               return val;
+       },
+
+       testChange = function testChange( e ) {
+               var elem = e.target, data, val;
+
+               if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
+                       return;
+               }
+
+               data = jQuery._data( elem, "_change_data" );
+               val = getVal(elem);
+
+               // the current data will be also retrieved by beforeactivate
+               if ( e.type !== "focusout" || elem.type !== "radio" ) {
+                       jQuery._data( elem, "_change_data", val );
+               }
+
+               if ( data === undefined || val === data ) {
+                       return;
+               }
+
+               if ( data != null || val ) {
+                       e.type = "change";
+                       e.liveFired = undefined;
+                       jQuery.event.trigger( e, arguments[1], elem );
+               }
+       };
+
+       jQuery.event.special.change = {
+               filters: {
+                       focusout: testChange,
+
+                       beforedeactivate: testChange,
+
+                       click: function( e ) {
+                               var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
+
+                               if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
+                                       testChange.call( this, e );
+                               }
+                       },
+
+                       // Change has to be called before submit
+                       // Keydown will be called before keypress, which is used in submit-event delegation
+                       keydown: function( e ) {
+                               var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
+
+                               if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
+                                       (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+                                       type === "select-multiple" ) {
+                                       testChange.call( this, e );
+                               }
+                       },
+
+                       // Beforeactivate happens also before the previous element is blurred
+                       // with this event you can't trigger a change event, but you can store
+                       // information
+                       beforeactivate: function( e ) {
+                               var elem = e.target;
+                               jQuery._data( elem, "_change_data", getVal(elem) );
+                       }
+               },
+
+               setup: function( data, namespaces ) {
+                       if ( this.type === "file" ) {
+                               return false;
+                       }
+
+                       for ( var type in changeFilters ) {
+                               jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
+                       }
+
+                       return rformElems.test( this.nodeName );
+               },
+
+               teardown: function( namespaces ) {
+                       jQuery.event.remove( this, ".specialChange" );
+
+                       return rformElems.test( this.nodeName );
+               }
+       };
+
+       changeFilters = jQuery.event.special.change.filters;
+
+       // Handle when the input is .focus()'d
+       changeFilters.focus = changeFilters.beforeactivate;
+}
+
+function trigger( type, elem, args ) {
+       // Piggyback on a donor event to simulate a different one.
+       // Fake originalEvent to avoid donor's stopPropagation, but if the
+       // simulated event prevents default then we do the same on the donor.
+       // Don't pass args or remember liveFired; they apply to the donor event.
+       var event = jQuery.extend( {}, args[ 0 ] );
+       event.type = type;
+       event.originalEvent = {};
+       event.liveFired = undefined;
+       jQuery.event.handle.call( elem, event );
+       if ( event.isDefaultPrevented() ) {
+               args[ 0 ].preventDefault();
+       }
+}
+
+// Create "bubbling" focus and blur events
+if ( !jQuery.support.focusinBubbles ) {
+       jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+               // Attach a single capturing handler while someone wants focusin/focusout
+               var attaches = 0;
+
+               jQuery.event.special[ fix ] = {
+                       setup: function() {
+                               if ( attaches++ === 0 ) {
+                                       document.addEventListener( orig, handler, true );
+                               }
+                       },
+                       teardown: function() {
+                               if ( --attaches === 0 ) {
+                                       document.removeEventListener( orig, handler, true );
+                               }
+                       }
+               };
+
+               function handler( donor ) {
+                       // Donor event is always a native one; fix it and switch its type.
+                       // Let focusin/out handler cancel the donor focus/blur event.
+                       var e = jQuery.event.fix( donor );
+                       e.type = fix;
+                       e.originalEvent = {};
+                       jQuery.event.trigger( e, null, e.target );
+                       if ( e.isDefaultPrevented() ) {
+                               donor.preventDefault();
+                       }
+               }
+       });
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+       jQuery.fn[ name ] = function( type, data, fn ) {
+               var handler;
+
+               // Handle object literals
+               if ( typeof type === "object" ) {
+                       for ( var key in type ) {
+                               this[ name ](key, data, type[key], fn);
+                       }
+                       return this;
+               }
+
+               if ( arguments.length === 2 || data === false ) {
+                       fn = data;
+                       data = undefined;
+               }
+
+               if ( name === "one" ) {
+                       handler = function( event ) {
+                               jQuery( this ).unbind( event, handler );
+                               return fn.apply( this, arguments );
+                       };
+                       handler.guid = fn.guid || jQuery.guid++;
+               } else {
+                       handler = fn;
+               }
+
+               if ( type === "unload" && name !== "one" ) {
+                       this.one( type, data, fn );
+
+               } else {
+                       for ( var i = 0, l = this.length; i < l; i++ ) {
+                               jQuery.event.add( this[i], type, handler, data );
+                       }
+               }
+
+               return this;
+       };
+});
+
+jQuery.fn.extend({
+       unbind: function( type, fn ) {
+               // Handle object literals
+               if ( typeof type === "object" && !type.preventDefault ) {
+                       for ( var key in type ) {
+                               this.unbind(key, type[key]);
+                       }
+
+               } else {
+                       for ( var i = 0, l = this.length; i < l; i++ ) {
+                               jQuery.event.remove( this[i], type, fn );
+                       }
+               }
+
+               return this;
+       },
+
+       delegate: function( selector, types, data, fn ) {
+               return this.live( types, data, fn, selector );
+       },
+
+       undelegate: function( selector, types, fn ) {
+               if ( arguments.length === 0 ) {
+                       return this.unbind( "live" );
+
+               } else {
+                       return this.die( types, null, fn, selector );
+               }
+       },
+
+       trigger: function( type, data ) {
+               return this.each(function() {
+                       jQuery.event.trigger( type, data, this );
+               });
+       },
+
+       triggerHandler: function( type, data ) {
+               if ( this[0] ) {
+                       return jQuery.event.trigger( type, data, this[0], true );
+               }
+       },
+
+       toggle: function( fn ) {
+               // Save reference to arguments for access in closure
+               var args = arguments,
+                       guid = fn.guid || jQuery.guid++,
+                       i = 0,
+                       toggler = function( event ) {
+                               // Figure out which function to execute
+                               var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+                               jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+                               // Make sure that clicks stop
+                               event.preventDefault();
+
+                               // and execute the function
+                               return args[ lastToggle ].apply( this, arguments ) || false;
+                       };
+
+               // link all the functions, so any of them can unbind this click handler
+               toggler.guid = guid;
+               while ( i < args.length ) {
+                       args[ i++ ].guid = guid;
+               }
+
+               return this.click( toggler );
+       },
+
+       hover: function( fnOver, fnOut ) {
+               return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+       }
+});
+
+var liveMap = {
+       focus: "focusin",
+       blur: "focusout",
+       mouseenter: "mouseover",
+       mouseleave: "mouseout"
+};
+
+jQuery.each(["live", "die"], function( i, name ) {
+       jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
+               var type, i = 0, match, namespaces, preType,
+                       selector = origSelector || this.selector,
+                       context = origSelector ? this : jQuery( this.context );
+
+               if ( typeof types === "object" && !types.preventDefault ) {
+                       for ( var key in types ) {
+                               context[ name ]( key, data, types[key], selector );
+                       }
+
+                       return this;
+               }
+
+               if ( name === "die" && !types &&
+                                       origSelector && origSelector.charAt(0) === "." ) {
+
+                       context.unbind( origSelector );
+
+                       return this;
+               }
+
+               if ( data === false || jQuery.isFunction( data ) ) {
+                       fn = data || returnFalse;
+                       data = undefined;
+               }
+
+               types = (types || "").split(" ");
+
+               while ( (type = types[ i++ ]) != null ) {
+                       match = rnamespaces.exec( type );
+                       namespaces = "";
+
+                       if ( match )  {
+                               namespaces = match[0];
+                               type = type.replace( rnamespaces, "" );
+                       }
+
+                       if ( type === "hover" ) {
+                               types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
+                               continue;
+                       }
+
+                       preType = type;
+
+                       if ( liveMap[ type ] ) {
+                               types.push( liveMap[ type ] + namespaces );
+                               type = type + namespaces;
+
+                       } else {
+                               type = (liveMap[ type ] || type) + namespaces;
+                       }
+
+                       if ( name === "live" ) {
+                               // bind live handler
+                               for ( var j = 0, l = context.length; j < l; j++ ) {
+                                       jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
+                                               { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
+                               }
+
+                       } else {
+                               // unbind live handler
+                               context.unbind( "live." + liveConvert( type, selector ), fn );
+                       }
+               }
+
+               return this;
+       };
+});
+
+function liveHandler( event ) {
+       var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
+               elems = [],
+               selectors = [],
+               events = jQuery._data( this, "events" );
+
+       // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
+       if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
+               return;
+       }
+
+       if ( event.namespace ) {
+               namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
+       }
+
+       event.liveFired = this;
+
+       var live = events.live.slice(0);
+
+       for ( j = 0; j < live.length; j++ ) {
+               handleObj = live[j];
+
+               if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
+                       selectors.push( handleObj.selector );
+
+               } else {
+                       live.splice( j--, 1 );
+               }
+       }
+
+       match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+       for ( i = 0, l = match.length; i < l; i++ ) {
+               close = match[i];
+
+               for ( j = 0; j < live.length; j++ ) {
+                       handleObj = live[j];
+
+                       if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
+                               elem = close.elem;
+                               related = null;
+
+                               // Those two events require additional checking
+                               if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
+                                       event.type = handleObj.preType;
+                                       related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+
+                                       // Make sure not to accidentally match a child element with the same selector
+                                       if ( related && jQuery.contains( elem, related ) ) {
+                                               related = elem;
+                                       }
+                               }
+
+                               if ( !related || related !== elem ) {
+                                       elems.push({ elem: elem, handleObj: handleObj, level: close.level });
+                               }
+                       }
+               }
+       }
+
+       for ( i = 0, l = elems.length; i < l; i++ ) {
+               match = elems[i];
+
+               if ( maxLevel && match.level > maxLevel ) {
+                       break;
+               }
+
+               event.currentTarget = match.elem;
+               event.data = match.handleObj.data;
+               event.handleObj = match.handleObj;
+
+               ret = match.handleObj.origHandler.apply( match.elem, arguments );
+
+               if ( ret === false || event.isPropagationStopped() ) {
+                       maxLevel = match.level;
+
+                       if ( ret === false ) {
+                               stop = false;
+                       }
+                       if ( event.isImmediatePropagationStopped() ) {
+                               break;
+                       }
+               }
+       }
+
+       return stop;
+}
+
+function liveConvert( type, selector ) {
+       return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
+}
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+       "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+       "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+       // Handle event binding
+       jQuery.fn[ name ] = function( data, fn ) {
+               if ( fn == null ) {
+                       fn = data;
+                       data = null;
+               }
+
+               return arguments.length > 0 ?
+                       this.bind( name, data, fn ) :
+                       this.trigger( name );
+       };
+
+       if ( jQuery.attrFn ) {
+               jQuery.attrFn[ name ] = true;
+       }
+});
+
+
+
+/*!
+ * Sizzle CSS Selector Engine
+ *  Copyright 2011, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+       done = 0,
+       toString = Object.prototype.toString,
+       hasDuplicate = false,
+       baseHasDuplicate = true,
+       rBackslash = /\\/g,
+       rNonWord = /\W/;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+//   Thus far that includes Google Chrome.
+[0, 0].sort(function() {
+       baseHasDuplicate = false;
+       return 0;
+});
+
+var Sizzle = function( selector, context, results, seed ) {
+       results = results || [];
+       context = context || document;
+
+       var origContext = context;
+
+       if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+               return [];
+       }
+       
+       if ( !selector || typeof selector !== "string" ) {
+               return results;
+       }
+
+       var m, set, checkSet, extra, ret, cur, pop, i,
+               prune = true,
+               contextXML = Sizzle.isXML( context ),
+               parts = [],
+               soFar = selector;
+       
+       // Reset the position of the chunker regexp (start from head)
+       do {
+               chunker.exec( "" );
+               m = chunker.exec( soFar );
+
+               if ( m ) {
+                       soFar = m[3];
+               
+                       parts.push( m[1] );
+               
+                       if ( m[2] ) {
+                               extra = m[3];
+                               break;
+                       }
+               }
+       } while ( m );
+
+       if ( parts.length > 1 && origPOS.exec( selector ) ) {
+
+               if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+                       set = posProcess( parts[0] + parts[1], context );
+
+               } else {
+                       set = Expr.relative[ parts[0] ] ?
+                               [ context ] :
+                               Sizzle( parts.shift(), context );
+
+                       while ( parts.length ) {
+                               selector = parts.shift();
+
+                               if ( Expr.relative[ selector ] ) {
+                                       selector += parts.shift();
+                               }
+                               
+                               set = posProcess( selector, set );
+                       }
+               }
+
+       } else {
+               // Take a shortcut and set the context if the root selector is an ID
+               // (but not if it'll be faster if the inner selector is an ID)
+               if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+                               Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+
+                       ret = Sizzle.find( parts.shift(), context, contextXML );
+                       context = ret.expr ?
+                               Sizzle.filter( ret.expr, ret.set )[0] :
+                               ret.set[0];
+               }
+
+               if ( context ) {
+                       ret = seed ?
+                               { expr: parts.pop(), set: makeArray(seed) } :
+                               Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+
+                       set = ret.expr ?
+                               Sizzle.filter( ret.expr, ret.set ) :
+                               ret.set;
+
+                       if ( parts.length > 0 ) {
+                               checkSet = makeArray( set );
+
+                       } else {
+                               prune = false;
+                       }
+
+                       while ( parts.length ) {
+                               cur = parts.pop();
+                               pop = cur;
+
+                               if ( !Expr.relative[ cur ] ) {
+                                       cur = "";
+                               } else {
+                                       pop = parts.pop();
+                               }
+
+                               if ( pop == null ) {
+                                       pop = context;
+                               }
+
+                               Expr.relative[ cur ]( checkSet, pop, contextXML );
+                       }
+
+               } else {
+                       checkSet = parts = [];
+               }
+       }
+
+       if ( !checkSet ) {
+               checkSet = set;
+       }
+
+       if ( !checkSet ) {
+               Sizzle.error( cur || selector );
+       }
+
+       if ( toString.call(checkSet) === "[object Array]" ) {
+               if ( !prune ) {
+                       results.push.apply( results, checkSet );
+
+               } else if ( context && context.nodeType === 1 ) {
+                       for ( i = 0; checkSet[i] != null; i++ ) {
+                               if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
+                                       results.push( set[i] );
+                               }
+                       }
+
+               } else {
+                       for ( i = 0; checkSet[i] != null; i++ ) {
+                               if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+                                       results.push( set[i] );
+                               }
+                       }
+               }
+
+       } else {
+               makeArray( checkSet, results );
+       }
+
+       if ( extra ) {
+               Sizzle( extra, origContext, results, seed );
+               Sizzle.uniqueSort( results );
+       }
+
+       return results;
+};
+
+Sizzle.uniqueSort = function( results ) {
+       if ( sortOrder ) {
+               hasDuplicate = baseHasDuplicate;
+               results.sort( sortOrder );
+
+               if ( hasDuplicate ) {
+                       for ( var i = 1; i < results.length; i++ ) {
+                               if ( results[i] === results[ i - 1 ] ) {
+                                       results.splice( i--, 1 );
+                               }
+                       }
+               }
+       }
+
+       return results;
+};
+
+Sizzle.matches = function( expr, set ) {
+       return Sizzle( expr, null, null, set );
+};
+
+Sizzle.matchesSelector = function( node, expr ) {
+       return Sizzle( expr, null, null, [node] ).length > 0;
+};
+
+Sizzle.find = function( expr, context, isXML ) {
+       var set;
+
+       if ( !expr ) {
+               return [];
+       }
+
+       for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+               var match,
+                       type = Expr.order[i];
+               
+               if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+                       var left = match[1];
+                       match.splice( 1, 1 );
+
+                       if ( left.substr( left.length - 1 ) !== "\\" ) {
+                               match[1] = (match[1] || "").replace( rBackslash, "" );
+                               set = Expr.find[ type ]( match, context, isXML );
+
+                               if ( set != null ) {
+                                       expr = expr.replace( Expr.match[ type ], "" );
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       if ( !set ) {
+               set = typeof context.getElementsByTagName !== "undefined" ?
+                       context.getElementsByTagName( "*" ) :
+                       [];
+       }
+
+       return { set: set, expr: expr };
+};
+
+Sizzle.filter = function( expr, set, inplace, not ) {
+       var match, anyFound,
+               old = expr,
+               result = [],
+               curLoop = set,
+               isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
+
+       while ( expr && set.length ) {
+               for ( var type in Expr.filter ) {
+                       if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+                               var found, item,
+                                       filter = Expr.filter[ type ],
+                                       left = match[1];
+
+                               anyFound = false;
+
+                               match.splice(1,1);
+
+                               if ( left.substr( left.length - 1 ) === "\\" ) {
+                                       continue;
+                               }
+
+                               if ( curLoop === result ) {
+                                       result = [];
+                               }
+
+                               if ( Expr.preFilter[ type ] ) {
+                                       match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+                                       if ( !match ) {
+                                               anyFound = found = true;
+
+                                       } else if ( match === true ) {
+                                               continue;
+                                       }
+                               }
+
+                               if ( match ) {
+                                       for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+                                               if ( item ) {
+                                                       found = filter( item, match, i, curLoop );
+                                                       var pass = not ^ !!found;
+
+                                                       if ( inplace && found != null ) {
+                                                               if ( pass ) {
+                                                                       anyFound = true;
+
+                                                               } else {
+                                                                       curLoop[i] = false;
+                                                               }
+
+                                                       } else if ( pass ) {
+                                                               result.push( item );
+                                                               anyFound = true;
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               if ( found !== undefined ) {
+                                       if ( !inplace ) {
+                                               curLoop = result;
+                                       }
+
+                                       expr = expr.replace( Expr.match[ type ], "" );
+
+                                       if ( !anyFound ) {
+                                               return [];
+                                       }
+
+                                       break;
+                               }
+                       }
+               }
+
+               // Improper expression
+               if ( expr === old ) {
+                       if ( anyFound == null ) {
+                               Sizzle.error( expr );
+
+                       } else {
+                               break;
+                       }
+               }
+
+               old = expr;
+       }
+
+       return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+       throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+       order: [ "ID", "NAME", "TAG" ],
+
+       match: {
+               ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+               CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+               NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
+               ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
+               TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
+               CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
+               POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
+               PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+       },
+
+       leftMatch: {},
+
+       attrMap: {
+               "class": "className",
+               "for": "htmlFor"
+       },
+
+       attrHandle: {
+               href: function( elem ) {
+                       return elem.getAttribute( "href" );
+               },
+               type: function( elem ) {
+                       return elem.getAttribute( "type" );
+               }
+       },
+
+       relative: {
+               "+": function(checkSet, part){
+                       var isPartStr = typeof part === "string",
+                               isTag = isPartStr && !rNonWord.test( part ),
+                               isPartStrNotTag = isPartStr && !isTag;
+
+                       if ( isTag ) {
+                               part = part.toLowerCase();
+                       }
+
+                       for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+                               if ( (elem = checkSet[i]) ) {
+                                       while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+                                       checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+                                               elem || false :
+                                               elem === part;
+                               }
+                       }
+
+                       if ( isPartStrNotTag ) {
+                               Sizzle.filter( part, checkSet, true );
+                       }
+               },
+
+               ">": function( checkSet, part ) {
+                       var elem,
+                               isPartStr = typeof part === "string",
+                               i = 0,
+                               l = checkSet.length;
+
+                       if ( isPartStr && !rNonWord.test( part ) ) {
+                               part = part.toLowerCase();
+
+                               for ( ; i < l; i++ ) {
+                                       elem = checkSet[i];
+
+                                       if ( elem ) {
+                                               var parent = elem.parentNode;
+                                               checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+                                       }
+                               }
+
+                       } else {
+                               for ( ; i < l; i++ ) {
+                                       elem = checkSet[i];
+
+                                       if ( elem ) {
+                                               checkSet[i] = isPartStr ?
+                                                       elem.parentNode :
+                                                       elem.parentNode === part;
+                                       }
+                               }
+
+                               if ( isPartStr ) {
+                                       Sizzle.filter( part, checkSet, true );
+                               }
+                       }
+               },
+
+               "": function(checkSet, part, isXML){
+                       var nodeCheck,
+                               doneName = done++,
+                               checkFn = dirCheck;
+
+                       if ( typeof part === "string" && !rNonWord.test( part ) ) {
+                               part = part.toLowerCase();
+                               nodeCheck = part;
+                               checkFn = dirNodeCheck;
+                       }
+
+                       checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
+               },
+
+               "~": function( checkSet, part, isXML ) {
+                       var nodeCheck,
+                               doneName = done++,
+                               checkFn = dirCheck;
+
+                       if ( typeof part === "string" && !rNonWord.test( part ) ) {
+                               part = part.toLowerCase();
+                               nodeCheck = part;
+                               checkFn = dirNodeCheck;
+                       }
+
+                       checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
+               }
+       },
+
+       find: {
+               ID: function( match, context, isXML ) {
+                       if ( typeof context.getElementById !== "undefined" && !isXML ) {
+                               var m = context.getElementById(match[1]);
+                               // Check parentNode to catch when Blackberry 4.6 returns
+                               // nodes that are no longer in the document #6963
+                               return m && m.parentNode ? [m] : [];
+                       }
+               },
+
+               NAME: function( match, context ) {
+                       if ( typeof context.getElementsByName !== "undefined" ) {
+                               var ret = [],
+                                       results = context.getElementsByName( match[1] );
+
+                               for ( var i = 0, l = results.length; i < l; i++ ) {
+                                       if ( results[i].getAttribute("name") === match[1] ) {
+                                               ret.push( results[i] );
+                                       }
+                               }
+
+                               return ret.length === 0 ? null : ret;
+                       }
+               },
+
+               TAG: function( match, context ) {
+                       if ( typeof context.getElementsByTagName !== "undefined" ) {
+                               return context.getElementsByTagName( match[1] );
+                       }
+               }
+       },
+       preFilter: {
+               CLASS: function( match, curLoop, inplace, result, not, isXML ) {
+                       match = " " + match[1].replace( rBackslash, "" ) + " ";
+
+                       if ( isXML ) {
+                               return match;
+                       }
+
+                       for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+                               if ( elem ) {
+                                       if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
+                                               if ( !inplace ) {
+                                                       result.push( elem );
+                                               }
+
+                                       } else if ( inplace ) {
+                                               curLoop[i] = false;
+                                       }
+                               }
+                       }
+
+                       return false;
+               },
+
+               ID: function( match ) {
+                       return match[1].replace( rBackslash, "" );
+               },
+
+               TAG: function( match, curLoop ) {
+                       return match[1].replace( rBackslash, "" ).toLowerCase();
+               },
+
+               CHILD: function( match ) {
+                       if ( match[1] === "nth" ) {
+                               if ( !match[2] ) {
+                                       Sizzle.error( match[0] );
+                               }
+
+                               match[2] = match[2].replace(/^\+|\s*/g, '');
+
+                               // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+                               var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
+                                       match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+                                       !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+                               // calculate the numbers (first)n+(last) including if they are negative
+                               match[2] = (test[1] + (test[2] || 1)) - 0;
+                               match[3] = test[3] - 0;
+                       }
+                       else if ( match[2] ) {
+                               Sizzle.error( match[0] );
+                       }
+
+                       // TODO: Move to normal caching system
+                       match[0] = done++;
+
+                       return match;
+               },
+
+               ATTR: function( match, curLoop, inplace, result, not, isXML ) {
+                       var name = match[1] = match[1].replace( rBackslash, "" );
+                       
+                       if ( !isXML && Expr.attrMap[name] ) {
+                               match[1] = Expr.attrMap[name];
+                       }
+
+                       // Handle if an un-quoted value was used
+                       match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
+
+                       if ( match[2] === "~=" ) {
+                               match[4] = " " + match[4] + " ";
+                       }
+
+                       return match;
+               },
+
+               PSEUDO: function( match, curLoop, inplace, result, not ) {
+                       if ( match[1] === "not" ) {
+                               // If we're dealing with a complex expression, or a simple one
+                               if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+                                       match[3] = Sizzle(match[3], null, null, curLoop);
+
+                               } else {
+                                       var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+
+                                       if ( !inplace ) {
+                                               result.push.apply( result, ret );
+                                       }
+
+                                       return false;
+                               }
+
+                       } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+                               return true;
+                       }
+                       
+                       return match;
+               },
+
+               POS: function( match ) {
+                       match.unshift( true );
+
+                       return match;
+               }
+       },
+       
+       filters: {
+               enabled: function( elem ) {
+                       return elem.disabled === false && elem.type !== "hidden";
+               },
+
+               disabled: function( elem ) {
+                       return elem.disabled === true;
+               },
+
+               checked: function( elem ) {
+                       return elem.checked === true;
+               },
+               
+               selected: function( elem ) {
+                       // Accessing this property makes selected-by-default
+                       // options in Safari work properly
+                       if ( elem.parentNode ) {
+                               elem.parentNode.selectedIndex;
+                       }
+                       
+                       return elem.selected === true;
+               },
+
+               parent: function( elem ) {
+                       return !!elem.firstChild;
+               },
+
+               empty: function( elem ) {
+                       return !elem.firstChild;
+               },
+
+               has: function( elem, i, match ) {
+                       return !!Sizzle( match[3], elem ).length;
+               },
+
+               header: function( elem ) {
+                       return (/h\d/i).test( elem.nodeName );
+               },
+
+               text: function( elem ) {
+                       var attr = elem.getAttribute( "type" ), type = elem.type;
+                       // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 
+                       // use getAttribute instead to test this case
+                       return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
+               },
+
+               radio: function( elem ) {
+                       return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
+               },
+
+               checkbox: function( elem ) {
+                       return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
+               },
+
+               file: function( elem ) {
+                       return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
+               },
+
+               password: function( elem ) {
+                       return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
+               },
+
+               submit: function( elem ) {
+                       var name = elem.nodeName.toLowerCase();
+                       return (name === "input" || name === "button") && "submit" === elem.type;
+               },
+
+               image: function( elem ) {
+                       return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
+               },
+
+               reset: function( elem ) {
+                       return elem.nodeName.toLowerCase() === "input" && "reset" === elem.type;
+               },
+
+               button: function( elem ) {
+                       var name = elem.nodeName.toLowerCase();
+                       return name === "input" && "button" === elem.type || name === "button";
+               },
+
+               input: function( elem ) {
+                       return (/input|select|textarea|button/i).test( elem.nodeName );
+               },
+
+               focus: function( elem ) {
+                       return elem === elem.ownerDocument.activeElement;
+               }
+       },
+       setFilters: {
+               first: function( elem, i ) {
+                       return i === 0;
+               },
+
+               last: function( elem, i, match, array ) {
+                       return i === array.length - 1;
+               },
+
+               even: function( elem, i ) {
+                       return i % 2 === 0;
+               },
+
+               odd: function( elem, i ) {
+                       return i % 2 === 1;
+               },
+
+               lt: function( elem, i, match ) {
+                       return i < match[3] - 0;
+               },
+
+               gt: function( elem, i, match ) {
+                       return i > match[3] - 0;
+               },
+
+               nth: function( elem, i, match ) {
+                       return match[3] - 0 === i;
+               },
+
+               eq: function( elem, i, match ) {
+                       return match[3] - 0 === i;
+               }
+       },
+       filter: {
+               PSEUDO: function( elem, match, i, array ) {
+                       var name = match[1],
+                               filter = Expr.filters[ name ];
+
+                       if ( filter ) {
+                               return filter( elem, i, match, array );
+
+                       } else if ( name === "contains" ) {
+                               return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
+
+                       } else if ( name === "not" ) {
+                               var not = match[3];
+
+                               for ( var j = 0, l = not.length; j < l; j++ ) {
+                                       if ( not[j] === elem ) {
+                                               return false;
+                                       }
+                               }
+
+                               return true;
+
+                       } else {
+                               Sizzle.error( name );
+                       }
+               },
+
+               CHILD: function( elem, match ) {
+                       var type = match[1],
+                               node = elem;
+
+                       switch ( type ) {
+                               case "only":
+                               case "first":
+                                       while ( (node = node.previousSibling) )  {
+                                               if ( node.nodeType === 1 ) { 
+                                                       return false; 
+                                               }
+                                       }
+
+                                       if ( type === "first" ) { 
+                                               return true; 
+                                       }
+
+                                       node = elem;
+
+                               case "last":
+                                       while ( (node = node.nextSibling) )      {
+                                               if ( node.nodeType === 1 ) { 
+                                                       return false; 
+                                               }
+                                       }
+
+                                       return true;
+
+                               case "nth":
+                                       var first = match[2],
+                                               last = match[3];
+
+                                       if ( first === 1 && last === 0 ) {
+                                               return true;
+                                       }
+                                       
+                                       var doneName = match[0],
+                                               parent = elem.parentNode;
+       
+                                       if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+                                               var count = 0;
+                                               
+                                               for ( node = parent.firstChild; node; node = node.nextSibling ) {
+                                                       if ( node.nodeType === 1 ) {
+                                                               node.nodeIndex = ++count;
+                                                       }
+                                               } 
+
+                                               parent.sizcache = doneName;
+                                       }
+                                       
+                                       var diff = elem.nodeIndex - last;
+
+                                       if ( first === 0 ) {
+                                               return diff === 0;
+
+                                       } else {
+                                               return ( diff % first === 0 && diff / first >= 0 );
+                                       }
+                       }
+               },
+
+               ID: function( elem, match ) {
+                       return elem.nodeType === 1 && elem.getAttribute("id") === match;
+               },
+
+               TAG: function( elem, match ) {
+                       return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+               },
+               
+               CLASS: function( elem, match ) {
+                       return (" " + (elem.className || elem.getAttribute("class")) + " ")
+                               .indexOf( match ) > -1;
+               },
+
+               ATTR: function( elem, match ) {
+                       var name = match[1],
+                               result = Expr.attrHandle[ name ] ?
+                                       Expr.attrHandle[ name ]( elem ) :
+                                       elem[ name ] != null ?
+                                               elem[ name ] :
+                                               elem.getAttribute( name ),
+                               value = result + "",
+                               type = match[2],
+                               check = match[4];
+
+                       return result == null ?
+                               type === "!=" :
+                               type === "=" ?
+                               value === check :
+                               type === "*=" ?
+                               value.indexOf(check) >= 0 :
+                               type === "~=" ?
+                               (" " + value + " ").indexOf(check) >= 0 :
+                               !check ?
+                               value && result !== false :
+                               type === "!=" ?
+                               value !== check :
+                               type === "^=" ?
+                               value.indexOf(check) === 0 :
+                               type === "$=" ?
+                               value.substr(value.length - check.length) === check :
+                               type === "|=" ?
+                               value === check || value.substr(0, check.length + 1) === check + "-" :
+                               false;
+               },
+
+               POS: function( elem, match, i, array ) {
+                       var name = match[2],
+                               filter = Expr.setFilters[ name ];
+
+                       if ( filter ) {
+                               return filter( elem, i, match, array );
+                       }
+               }
+       }
+};
+
+var origPOS = Expr.match.POS,
+       fescape = function(all, num){
+               return "\\" + (num - 0 + 1);
+       };
+
+for ( var type in Expr.match ) {
+       Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
+       Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
+}
+
+var makeArray = function( array, results ) {
+       array = Array.prototype.slice.call( array, 0 );
+
+       if ( results ) {
+               results.push.apply( results, array );
+               return results;
+       }
+       
+       return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+       Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch( e ) {
+       makeArray = function( array, results ) {
+               var i = 0,
+                       ret = results || [];
+
+               if ( toString.call(array) === "[object Array]" ) {
+                       Array.prototype.push.apply( ret, array );
+
+               } else {
+                       if ( typeof array.length === "number" ) {
+                               for ( var l = array.length; i < l; i++ ) {
+                                       ret.push( array[i] );
+                               }
+
+                       } else {
+                               for ( ; array[i]; i++ ) {
+                                       ret.push( array[i] );
+                               }
+                       }
+               }
+
+               return ret;
+       };
+}
+
+var sortOrder, siblingCheck;
+
+if ( document.documentElement.compareDocumentPosition ) {
+       sortOrder = function( a, b ) {
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+               }
+
+               if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+                       return a.compareDocumentPosition ? -1 : 1;
+               }
+
+               return a.compareDocumentPosition(b) & 4 ? -1 : 1;
+       };
+
+} else {
+       sortOrder = function( a, b ) {
+               var al, bl,
+                       ap = [],
+                       bp = [],
+                       aup = a.parentNode,
+                       bup = b.parentNode,
+                       cur = aup;
+
+               // The nodes are identical, we can exit early
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+
+               // If the nodes are siblings (or identical) we can do a quick check
+               } else if ( aup === bup ) {
+                       return siblingCheck( a, b );
+
+               // If no parents were found then the nodes are disconnected
+               } else if ( !aup ) {
+                       return -1;
+
+               } else if ( !bup ) {
+                       return 1;
+               }
+
+               // Otherwise they're somewhere else in the tree so we need
+               // to build up a full list of the parentNodes for comparison
+               while ( cur ) {
+                       ap.unshift( cur );
+                       cur = cur.parentNode;
+               }
+
+               cur = bup;
+
+               while ( cur ) {
+                       bp.unshift( cur );
+                       cur = cur.parentNode;
+               }
+
+               al = ap.length;
+               bl = bp.length;
+
+               // Start walking down the tree looking for a discrepancy
+               for ( var i = 0; i < al && i < bl; i++ ) {
+                       if ( ap[i] !== bp[i] ) {
+                               return siblingCheck( ap[i], bp[i] );
+                       }
+               }
+
+               // We ended someplace up the tree so do a sibling check
+               return i === al ?
+                       siblingCheck( a, bp[i], -1 ) :
+                       siblingCheck( ap[i], b, 1 );
+       };
+
+       siblingCheck = function( a, b, ret ) {
+               if ( a === b ) {
+                       return ret;
+               }
+
+               var cur = a.nextSibling;
+
+               while ( cur ) {
+                       if ( cur === b ) {
+                               return -1;
+                       }
+
+                       cur = cur.nextSibling;
+               }
+
+               return 1;
+       };
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+Sizzle.getText = function( elems ) {
+       var ret = "", elem;
+
+       for ( var i = 0; elems[i]; i++ ) {
+               elem = elems[i];
+
+               // Get the text from text nodes and CDATA nodes
+               if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+                       ret += elem.nodeValue;
+
+               // Traverse everything else, except comment nodes
+               } else if ( elem.nodeType !== 8 ) {
+                       ret += Sizzle.getText( elem.childNodes );
+               }
+       }
+
+       return ret;
+};
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+       // We're going to inject a fake input element with a specified name
+       var form = document.createElement("div"),
+               id = "script" + (new Date()).getTime(),
+               root = document.documentElement;
+
+       form.innerHTML = "<a name='" + id + "'/>";
+
+       // Inject it into the root element, check its status, and remove it quickly
+       root.insertBefore( form, root.firstChild );
+
+       // The workaround has to do additional checks after a getElementById
+       // Which slows things down for other browsers (hence the branching)
+       if ( document.getElementById( id ) ) {
+               Expr.find.ID = function( match, context, isXML ) {
+                       if ( typeof context.getElementById !== "undefined" && !isXML ) {
+                               var m = context.getElementById(match[1]);
+
+                               return m ?
+                                       m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
+                                               [m] :
+                                               undefined :
+                                       [];
+                       }
+               };
+
+               Expr.filter.ID = function( elem, match ) {
+                       var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+
+                       return elem.nodeType === 1 && node && node.nodeValue === match;
+               };
+       }
+
+       root.removeChild( form );
+
+       // release memory in IE
+       root = form = null;
+})();
+
+(function(){
+       // Check to see if the browser returns only elements
+       // when doing getElementsByTagName("*")
+
+       // Create a fake element
+       var div = document.createElement("div");
+       div.appendChild( document.createComment("") );
+
+       // Make sure no comments are found
+       if ( div.getElementsByTagName("*").length > 0 ) {
+               Expr.find.TAG = function( match, context ) {
+                       var results = context.getElementsByTagName( match[1] );
+
+                       // Filter out possible comments
+                       if ( match[1] === "*" ) {
+                               var tmp = [];
+
+                               for ( var i = 0; results[i]; i++ ) {
+                                       if ( results[i].nodeType === 1 ) {
+                                               tmp.push( results[i] );
+                                       }
+                               }
+
+                               results = tmp;
+                       }
+
+                       return results;
+               };
+       }
+
+       // Check to see if an attribute returns normalized href attributes
+       div.innerHTML = "<a href='#'></a>";
+
+       if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+                       div.firstChild.getAttribute("href") !== "#" ) {
+
+               Expr.attrHandle.href = function( elem ) {
+                       return elem.getAttribute( "href", 2 );
+               };
+       }
+
+       // release memory in IE
+       div = null;
+})();
+
+if ( document.querySelectorAll ) {
+       (function(){
+               var oldSizzle = Sizzle,
+                       div = document.createElement("div"),
+                       id = "__sizzle__";
+
+               div.innerHTML = "<p class='TEST'></p>";
+
+               // Safari can't handle uppercase or unicode characters when
+               // in quirks mode.
+               if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+                       return;
+               }
+       
+               Sizzle = function( query, context, extra, seed ) {
+                       context = context || document;
+
+                       // Only use querySelectorAll on non-XML documents
+                       // (ID selectors don't work in non-HTML documents)
+                       if ( !seed && !Sizzle.isXML(context) ) {
+                               // See if we find a selector to speed up
+                               var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
+                               
+                               if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
+                                       // Speed-up: Sizzle("TAG")
+                                       if ( match[1] ) {
+                                               return makeArray( context.getElementsByTagName( query ), extra );
+                                       
+                                       // Speed-up: Sizzle(".CLASS")
+                                       } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
+                                               return makeArray( context.getElementsByClassName( match[2] ), extra );
+                                       }
+                               }
+                               
+                               if ( context.nodeType === 9 ) {
+                                       // Speed-up: Sizzle("body")
+                                       // The body element only exists once, optimize finding it
+                                       if ( query === "body" && context.body ) {
+                                               return makeArray( [ context.body ], extra );
+                                               
+                                       // Speed-up: Sizzle("#ID")
+                                       } else if ( match && match[3] ) {
+                                               var elem = context.getElementById( match[3] );
+
+                                               // Check parentNode to catch when Blackberry 4.6 returns
+                                               // nodes that are no longer in the document #6963
+                                               if ( elem && elem.parentNode ) {
+                                                       // Handle the case where IE and Opera return items
+                                                       // by name instead of ID
+                                                       if ( elem.id === match[3] ) {
+                                                               return makeArray( [ elem ], extra );
+                                                       }
+                                                       
+                                               } else {
+                                                       return makeArray( [], extra );
+                                               }
+                                       }
+                                       
+                                       try {
+                                               return makeArray( context.querySelectorAll(query), extra );
+                                       } catch(qsaError) {}
+
+                               // qSA works strangely on Element-rooted queries
+                               // We can work around this by specifying an extra ID on the root
+                               // and working up from there (Thanks to Andrew Dupont for the technique)
+                               // IE 8 doesn't work on object elements
+                               } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+                                       var oldContext = context,
+                                               old = context.getAttribute( "id" ),
+                                               nid = old || id,
+                                               hasParent = context.parentNode,
+                                               relativeHierarchySelector = /^\s*[+~]/.test( query );
+
+                                       if ( !old ) {
+                                               context.setAttribute( "id", nid );
+                                       } else {
+                                               nid = nid.replace( /'/g, "\\$&" );
+                                       }
+                                       if ( relativeHierarchySelector && hasParent ) {
+                                               context = context.parentNode;
+                                       }
+
+                                       try {
+                                               if ( !relativeHierarchySelector || hasParent ) {
+                                                       return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
+                                               }
+
+                                       } catch(pseudoError) {
+                                       } finally {
+                                               if ( !old ) {
+                                                       oldContext.removeAttribute( "id" );
+                                               }
+                                       }
+                               }
+                       }
+               
+                       return oldSizzle(query, context, extra, seed);
+               };
+
+               for ( var prop in oldSizzle ) {
+                       Sizzle[ prop ] = oldSizzle[ prop ];
+               }
+
+               // release memory in IE
+               div = null;
+       })();
+}
+
+(function(){
+       var html = document.documentElement,
+               matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
+
+       if ( matches ) {
+               // Check to see if it's possible to do matchesSelector
+               // on a disconnected node (IE 9 fails this)
+               var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
+                       pseudoWorks = false;
+
+               try {
+                       // This should fail with an exception
+                       // Gecko does not error, returns false instead
+                       matches.call( document.documentElement, "[test!='']:sizzle" );
+       
+               } catch( pseudoError ) {
+                       pseudoWorks = true;
+               }
+
+               Sizzle.matchesSelector = function( node, expr ) {
+                       // Make sure that attribute selectors are quoted
+                       expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
+
+                       if ( !Sizzle.isXML( node ) ) {
+                               try { 
+                                       if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
+                                               var ret = matches.call( node, expr );
+
+                                               // IE 9's matchesSelector returns false on disconnected nodes
+                                               if ( ret || !disconnectedMatch ||
+                                                               // As well, disconnected nodes are said to be in a document
+                                                               // fragment in IE 9, so check for that
+                                                               node.document && node.document.nodeType !== 11 ) {
+                                                       return ret;
+                                               }
+                                       }
+                               } catch(e) {}
+                       }
+
+                       return Sizzle(expr, null, null, [node]).length > 0;
+               };
+       }
+})();
+
+(function(){
+       var div = document.createElement("div");
+
+       div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+       // Opera can't find a second classname (in 9.6)
+       // Also, make sure that getElementsByClassName actually exists
+       if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+               return;
+       }
+
+       // Safari caches class attributes, doesn't catch changes (in 3.2)
+       div.lastChild.className = "e";
+
+       if ( div.getElementsByClassName("e").length === 1 ) {
+               return;
+       }
+       
+       Expr.order.splice(1, 0, "CLASS");
+       Expr.find.CLASS = function( match, context, isXML ) {
+               if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+                       return context.getElementsByClassName(match[1]);
+               }
+       };
+
+       // release memory in IE
+       div = null;
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+       for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+               var elem = checkSet[i];
+
+               if ( elem ) {
+                       var match = false;
+
+                       elem = elem[dir];
+
+                       while ( elem ) {
+                               if ( elem.sizcache === doneName ) {
+                                       match = checkSet[elem.sizset];
+                                       break;
+                               }
+
+                               if ( elem.nodeType === 1 && !isXML ){
+                                       elem.sizcache = doneName;
+                                       elem.sizset = i;
+                               }
+
+                               if ( elem.nodeName.toLowerCase() === cur ) {
+                                       match = elem;
+                                       break;
+                               }
+
+                               elem = elem[dir];
+                       }
+
+                       checkSet[i] = match;
+               }
+       }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+       for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+               var elem = checkSet[i];
+
+               if ( elem ) {
+                       var match = false;
+                       
+                       elem = elem[dir];
+
+                       while ( elem ) {
+                               if ( elem.sizcache === doneName ) {
+                                       match = checkSet[elem.sizset];
+                                       break;
+                               }
+
+                               if ( elem.nodeType === 1 ) {
+                                       if ( !isXML ) {
+                                               elem.sizcache = doneName;
+                                               elem.sizset = i;
+                                       }
+
+                                       if ( typeof cur !== "string" ) {
+                                               if ( elem === cur ) {
+                                                       match = true;
+                                                       break;
+                                               }
+
+                                       } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+                                               match = elem;
+                                               break;
+                                       }
+                               }
+
+                               elem = elem[dir];
+                       }
+
+                       checkSet[i] = match;
+               }
+       }
+}
+
+if ( document.documentElement.contains ) {
+       Sizzle.contains = function( a, b ) {
+               return a !== b && (a.contains ? a.contains(b) : true);
+       };
+
+} else if ( document.documentElement.compareDocumentPosition ) {
+       Sizzle.contains = function( a, b ) {
+               return !!(a.compareDocumentPosition(b) & 16);
+       };
+
+} else {
+       Sizzle.contains = function() {
+               return false;
+       };
+}
+
+Sizzle.isXML = function( elem ) {
+       // documentElement is verified for cases where it doesn't yet exist
+       // (such as loading iframes in IE - #4833) 
+       var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+
+       return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function( selector, context ) {
+       var match,
+               tmpSet = [],
+               later = "",
+               root = context.nodeType ? [context] : context;
+
+       // Position selectors must be done after the filter
+       // And so must :not(positional) so we move all PSEUDOs to the end
+       while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+               later += match[0];
+               selector = selector.replace( Expr.match.PSEUDO, "" );
+       }
+
+       selector = Expr.relative[selector] ? selector + "*" : selector;
+
+       for ( var i = 0, l = root.length; i < l; i++ ) {
+               Sizzle( selector, root[i], tmpSet );
+       }
+
+       return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})();
+
+
+var runtil = /Until$/,
+       rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+       // Note: This RegExp should be improved, or likely pulled from Sizzle
+       rmultiselector = /,/,
+       isSimple = /^.[^:#\[\.,]*$/,
+       slice = Array.prototype.slice,
+       POS = jQuery.expr.match.POS,
+       // methods guaranteed to produce a unique set when starting from a unique set
+       guaranteedUnique = {
+               children: true,
+               contents: true,
+               next: true,
+               prev: true
+       };
+
+jQuery.fn.extend({
+       find: function( selector ) {
+               var self = this,
+                       i, l;
+
+               if ( typeof selector !== "string" ) {
+                       return jQuery( selector ).filter(function() {
+                               for ( i = 0, l = self.length; i < l; i++ ) {
+                                       if ( jQuery.contains( self[ i ], this ) ) {
+                                               return true;
+                                       }
+                               }
+                       });
+               }
+
+               var ret = this.pushStack( "", "find", selector ),
+                       length, n, r;
+
+               for ( i = 0, l = this.length; i < l; i++ ) {
+                       length = ret.length;
+                       jQuery.find( selector, this[i], ret );
+
+                       if ( i > 0 ) {
+                               // Make sure that the results are unique
+                               for ( n = length; n < ret.length; n++ ) {
+                                       for ( r = 0; r < length; r++ ) {
+                                               if ( ret[r] === ret[n] ) {
+                                                       ret.splice(n--, 1);
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               return ret;
+       },
+
+       has: function( target ) {
+               var targets = jQuery( target );
+               return this.filter(function() {
+                       for ( var i = 0, l = targets.length; i < l; i++ ) {
+                               if ( jQuery.contains( this, targets[i] ) ) {
+                                       return true;
+                               }
+                       }
+               });
+       },
+
+       not: function( selector ) {
+               return this.pushStack( winnow(this, selector, false), "not", selector);
+       },
+
+       filter: function( selector ) {
+               return this.pushStack( winnow(this, selector, true), "filter", selector );
+       },
+
+       is: function( selector ) {
+               return !!selector && ( typeof selector === "string" ?
+                       jQuery.filter( selector, this ).length > 0 :
+                       this.filter( selector ).length > 0 );
+       },
+
+       closest: function( selectors, context ) {
+               var ret = [], i, l, cur = this[0];
+               
+               // Array
+               if ( jQuery.isArray( selectors ) ) {
+                       var match, selector,
+                               matches = {},
+                               level = 1;
+
+                       if ( cur && selectors.length ) {
+                               for ( i = 0, l = selectors.length; i < l; i++ ) {
+                                       selector = selectors[i];
+
+                                       if ( !matches[ selector ] ) {
+                                               matches[ selector ] = POS.test( selector ) ?
+                                                       jQuery( selector, context || this.context ) :
+                                                       selector;
+                                       }
+                               }
+
+                               while ( cur && cur.ownerDocument && cur !== context ) {
+                                       for ( selector in matches ) {
+                                               match = matches[ selector ];
+
+                                               if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
+                                                       ret.push({ selector: selector, elem: cur, level: level });
+                                               }
+                                       }
+
+                                       cur = cur.parentNode;
+                                       level++;
+                               }
+                       }
+
+                       return ret;
+               }
+
+               // String
+               var pos = POS.test( selectors ) || typeof selectors !== "string" ?
+                               jQuery( selectors, context || this.context ) :
+                               0;
+
+               for ( i = 0, l = this.length; i < l; i++ ) {
+                       cur = this[i];
+
+                       while ( cur ) {
+                               if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+                                       ret.push( cur );
+                                       break;
+
+                               } else {
+                                       cur = cur.parentNode;
+                                       if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
+                                               break;
+                                       }
+                               }
+                       }
+               }
+
+               ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
+
+               return this.pushStack( ret, "closest", selectors );
+       },
+
+       // Determine the position of an element within
+       // the matched set of elements
+       index: function( elem ) {
+               if ( !elem || typeof elem === "string" ) {
+                       return jQuery.inArray( this[0],
+                               // If it receives a string, the selector is used
+                               // If it receives nothing, the siblings are used
+                               elem ? jQuery( elem ) : this.parent().children() );
+               }
+               // Locate the position of the desired element
+               return jQuery.inArray(
+                       // If it receives a jQuery object, the first element is used
+                       elem.jquery ? elem[0] : elem, this );
+       },
+
+       add: function( selector, context ) {
+               var set = typeof selector === "string" ?
+                               jQuery( selector, context ) :
+                               jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
+                       all = jQuery.merge( this.get(), set );
+
+               return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+                       all :
+                       jQuery.unique( all ) );
+       },
+
+       andSelf: function() {
+               return this.add( this.prevObject );
+       }
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+       return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+       parent: function( elem ) {
+               var parent = elem.parentNode;
+               return parent && parent.nodeType !== 11 ? parent : null;
+       },
+       parents: function( elem ) {
+               return jQuery.dir( elem, "parentNode" );
+       },
+       parentsUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "parentNode", until );
+       },
+       next: function( elem ) {
+               return jQuery.nth( elem, 2, "nextSibling" );
+       },
+       prev: function( elem ) {
+               return jQuery.nth( elem, 2, "previousSibling" );
+       },
+       nextAll: function( elem ) {
+               return jQuery.dir( elem, "nextSibling" );
+       },
+       prevAll: function( elem ) {
+               return jQuery.dir( elem, "previousSibling" );
+       },
+       nextUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "nextSibling", until );
+       },
+       prevUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "previousSibling", until );
+       },
+       siblings: function( elem ) {
+               return jQuery.sibling( elem.parentNode.firstChild, elem );
+       },
+       children: function( elem ) {
+               return jQuery.sibling( elem.firstChild );
+       },
+       contents: function( elem ) {
+               return jQuery.nodeName( elem, "iframe" ) ?
+                       elem.contentDocument || elem.contentWindow.document :
+                       jQuery.makeArray( elem.childNodes );
+       }
+}, function( name, fn ) {
+       jQuery.fn[ name ] = function( until, selector ) {
+               var ret = jQuery.map( this, fn, until ),
+                       // The variable 'args' was introduced in
+                       // https://github.com/jquery/jquery/commit/52a0238
+                       // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
+                       // http://code.google.com/p/v8/issues/detail?id=1050
+                       args = slice.call(arguments);
+
+               if ( !runtil.test( name ) ) {
+                       selector = until;
+               }
+
+               if ( selector && typeof selector === "string" ) {
+                       ret = jQuery.filter( selector, ret );
+               }
+
+               ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
+
+               if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+                       ret = ret.reverse();
+               }
+
+               return this.pushStack( ret, name, args.join(",") );
+       };
+});
+
+jQuery.extend({
+       filter: function( expr, elems, not ) {
+               if ( not ) {
+                       expr = ":not(" + expr + ")";
+               }
+
+               return elems.length === 1 ?
+                       jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+                       jQuery.find.matches(expr, elems);
+       },
+
+       dir: function( elem, dir, until ) {
+               var matched = [],
+                       cur = elem[ dir ];
+
+               while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+                       if ( cur.nodeType === 1 ) {
+                               matched.push( cur );
+                       }
+                       cur = cur[dir];
+               }
+               return matched;
+       },
+
+       nth: function( cur, result, dir, elem ) {
+               result = result || 1;
+               var num = 0;
+
+               for ( ; cur; cur = cur[dir] ) {
+                       if ( cur.nodeType === 1 && ++num === result ) {
+                               break;
+                       }
+               }
+
+               return cur;
+       },
+
+       sibling: function( n, elem ) {
+               var r = [];
+
+               for ( ; n; n = n.nextSibling ) {
+                       if ( n.nodeType === 1 && n !== elem ) {
+                               r.push( n );
+                       }
+               }
+
+               return r;
+       }
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, keep ) {
+
+       // Can't pass null or undefined to indexOf in Firefox 4
+       // Set to 0 to skip string check
+       qualifier = qualifier || 0;
+
+       if ( jQuery.isFunction( qualifier ) ) {
+               return jQuery.grep(elements, function( elem, i ) {
+                       var retVal = !!qualifier.call( elem, i, elem );
+                       return retVal === keep;
+               });
+
+       } else if ( qualifier.nodeType ) {
+               return jQuery.grep(elements, function( elem, i ) {
+                       return (elem === qualifier) === keep;
+               });
+
+       } else if ( typeof qualifier === "string" ) {
+               var filtered = jQuery.grep(elements, function( elem ) {
+                       return elem.nodeType === 1;
+               });
+
+               if ( isSimple.test( qualifier ) ) {
+                       return jQuery.filter(qualifier, filtered, !keep);
+               } else {
+                       qualifier = jQuery.filter( qualifier, filtered );
+               }
+       }
+
+       return jQuery.grep(elements, function( elem, i ) {
+               return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+       });
+}
+
+
+
+
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+       rleadingWhitespace = /^\s+/,
+       rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
+       rtagName = /<([\w:]+)/,
+       rtbody = /<tbody/i,
+       rhtml = /<|&#?\w+;/,
+       rnocache = /<(?:script|object|embed|option|style)/i,
+       // checked="checked" or checked
+       rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+       rscriptType = /\/(java|ecma)script/i,
+       wrapMap = {
+               option: [ 1, "<select multiple='multiple'>", "</select>" ],
+               legend: [ 1, "<fieldset>", "</fieldset>" ],
+               thead: [ 1, "<table>", "</table>" ],
+               tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+               td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+               col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+               area: [ 1, "<map>", "</map>" ],
+               _default: [ 0, "", "" ]
+       };
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+       wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+       text: function( text ) {
+               if ( jQuery.isFunction(text) ) {
+                       return this.each(function(i) {
+                               var self = jQuery( this );
+
+                               self.text( text.call(this, i, self.text()) );
+                       });
+               }
+
+               if ( typeof text !== "object" && text !== undefined ) {
+                       return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+               }
+
+               return jQuery.text( this );
+       },
+
+       wrapAll: function( html ) {
+               if ( jQuery.isFunction( html ) ) {
+                       return this.each(function(i) {
+                               jQuery(this).wrapAll( html.call(this, i) );
+                       });
+               }
+
+               if ( this[0] ) {
+                       // The elements to wrap the target around
+                       var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+                       if ( this[0].parentNode ) {
+                               wrap.insertBefore( this[0] );
+                       }
+
+                       wrap.map(function() {
+                               var elem = this;
+
+                               while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+                                       elem = elem.firstChild;
+                               }
+
+                               return elem;
+                       }).append( this );
+               }
+
+               return this;
+       },
+
+       wrapInner: function( html ) {
+               if ( jQuery.isFunction( html ) ) {
+                       return this.each(function(i) {
+                               jQuery(this).wrapInner( html.call(this, i) );
+                       });
+               }
+
+               return this.each(function() {
+                       var self = jQuery( this ),
+                               contents = self.contents();
+
+                       if ( contents.length ) {
+                               contents.wrapAll( html );
+
+                       } else {
+                               self.append( html );
+                       }
+               });
+       },
+
+       wrap: function( html ) {
+               return this.each(function() {
+                       jQuery( this ).wrapAll( html );
+               });
+       },
+
+       unwrap: function() {
+               return this.parent().each(function() {
+                       if ( !jQuery.nodeName( this, "body" ) ) {
+                               jQuery( this ).replaceWith( this.childNodes );
+                       }
+               }).end();
+       },
+
+       append: function() {
+               return this.domManip(arguments, true, function( elem ) {
+                       if ( this.nodeType === 1 ) {
+                               this.appendChild( elem );
+                       }
+               });
+       },
+
+       prepend: function() {
+               return this.domManip(arguments, true, function( elem ) {
+                       if ( this.nodeType === 1 ) {
+                               this.insertBefore( elem, this.firstChild );
+                       }
+               });
+       },
+
+       before: function() {
+               if ( this[0] && this[0].parentNode ) {
+                       return this.domManip(arguments, false, function( elem ) {
+                               this.parentNode.insertBefore( elem, this );
+                       });
+               } else if ( arguments.length ) {
+                       var set = jQuery(arguments[0]);
+                       set.push.apply( set, this.toArray() );
+                       return this.pushStack( set, "before", arguments );
+               }
+       },
+
+       after: function() {
+               if ( this[0] && this[0].parentNode ) {
+                       return this.domManip(arguments, false, function( elem ) {
+                               this.parentNode.insertBefore( elem, this.nextSibling );
+                       });
+               } else if ( arguments.length ) {
+                       var set = this.pushStack( this, "after", arguments );
+                       set.push.apply( set, jQuery(arguments[0]).toArray() );
+                       return set;
+               }
+       },
+
+       // keepData is for internal use only--do not document
+       remove: function( selector, keepData ) {
+               for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+                       if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+                               if ( !keepData && elem.nodeType === 1 ) {
+                                       jQuery.cleanData( elem.getElementsByTagName("*") );
+                                       jQuery.cleanData( [ elem ] );
+                               }
+
+                               if ( elem.parentNode ) {
+                                       elem.parentNode.removeChild( elem );
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       empty: function() {
+               for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+                       // Remove element nodes and prevent memory leaks
+                       if ( elem.nodeType === 1 ) {
+                               jQuery.cleanData( elem.getElementsByTagName("*") );
+                       }
+
+                       // Remove any remaining nodes
+                       while ( elem.firstChild ) {
+                               elem.removeChild( elem.firstChild );
+                       }
+               }
+
+               return this;
+       },
+
+       clone: function( dataAndEvents, deepDataAndEvents ) {
+               dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+               deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+               return this.map( function () {
+                       return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+               });
+       },
+
+       html: function( value ) {
+               if ( value === undefined ) {
+                       return this[0] && this[0].nodeType === 1 ?
+                               this[0].innerHTML.replace(rinlinejQuery, "") :
+                               null;
+
+               // See if we can take a shortcut and just use innerHTML
+               } else if ( typeof value === "string" && !rnocache.test( value ) &&
+                       (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+                       !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+                       value = value.replace(rxhtmlTag, "<$1></$2>");
+
+                       try {
+                               for ( var i = 0, l = this.length; i < l; i++ ) {
+                                       // Remove element nodes and prevent memory leaks
+                                       if ( this[i].nodeType === 1 ) {
+                                               jQuery.cleanData( this[i].getElementsByTagName("*") );
+                                               this[i].innerHTML = value;
+                                       }
+                               }
+
+                       // If using innerHTML throws an exception, use the fallback method
+                       } catch(e) {
+                               this.empty().append( value );
+                       }
+
+               } else if ( jQuery.isFunction( value ) ) {
+                       this.each(function(i){
+                               var self = jQuery( this );
+
+                               self.html( value.call(this, i, self.html()) );
+                       });
+
+               } else {
+                       this.empty().append( value );
+               }
+
+               return this;
+       },
+
+       replaceWith: function( value ) {
+               if ( this[0] && this[0].parentNode ) {
+                       // Make sure that the elements are removed from the DOM before they are inserted
+                       // this can help fix replacing a parent with child elements
+                       if ( jQuery.isFunction( value ) ) {
+                               return this.each(function(i) {
+                                       var self = jQuery(this), old = self.html();
+                                       self.replaceWith( value.call( this, i, old ) );
+                               });
+                       }
+
+                       if ( typeof value !== "string" ) {
+                               value = jQuery( value ).detach();
+                       }
+
+                       return this.each(function() {
+                               var next = this.nextSibling,
+                                       parent = this.parentNode;
+
+                               jQuery( this ).remove();
+
+                               if ( next ) {
+                                       jQuery(next).before( value );
+                               } else {
+                                       jQuery(parent).append( value );
+                               }
+                       });
+               } else {
+                       return this.length ?
+                               this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
+                               this;
+               }
+       },
+
+       detach: function( selector ) {
+               return this.remove( selector, true );
+       },
+
+       domManip: function( args, table, callback ) {
+               var results, first, fragment, parent,
+                       value = args[0],
+                       scripts = [];
+
+               // We can't cloneNode fragments that contain checked, in WebKit
+               if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+                       return this.each(function() {
+                               jQuery(this).domManip( args, table, callback, true );
+                       });
+               }
+
+               if ( jQuery.isFunction(value) ) {
+                       return this.each(function(i) {
+                               var self = jQuery(this);
+                               args[0] = value.call(this, i, table ? self.html() : undefined);
+                               self.domManip( args, table, callback );
+                       });
+               }
+
+               if ( this[0] ) {
+                       parent = value && value.parentNode;
+
+                       // If we're in a fragment, just use that instead of building a new one
+                       if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+                               results = { fragment: parent };
+
+                       } else {
+                               results = jQuery.buildFragment( args, this, scripts );
+                       }
+
+                       fragment = results.fragment;
+
+                       if ( fragment.childNodes.length === 1 ) {
+                               first = fragment = fragment.firstChild;
+                       } else {
+                               first = fragment.firstChild;
+                       }
+
+                       if ( first ) {
+                               table = table && jQuery.nodeName( first, "tr" );
+
+                               for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
+                                       callback.call(
+                                               table ?
+                                                       root(this[i], first) :
+                                                       this[i],
+                                               // Make sure that we do not leak memory by inadvertently discarding
+                                               // the original fragment (which might have attached data) instead of
+                                               // using it; in addition, use the original fragment object for the last
+                                               // item instead of first because it can end up being emptied incorrectly
+                                               // in certain situations (Bug #8070).
+                                               // Fragments from the fragment cache must always be cloned and never used
+                                               // in place.
+                                               results.cacheable || (l > 1 && i < lastIndex) ?
+                                                       jQuery.clone( fragment, true, true ) :
+                                                       fragment
+                                       );
+                               }
+                       }
+
+                       if ( scripts.length ) {
+                               jQuery.each( scripts, evalScript );
+                       }
+               }
+
+               return this;
+       }
+});
+
+function root( elem, cur ) {
+       return jQuery.nodeName(elem, "table") ?
+               (elem.getElementsByTagName("tbody")[0] ||
+               elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+               elem;
+}
+
+function cloneCopyEvent( src, dest ) {
+
+       if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+               return;
+       }
+
+       var internalKey = jQuery.expando,
+               oldData = jQuery.data( src ),
+               curData = jQuery.data( dest, oldData );
+
+       // Switch to use the internal data object, if it exists, for the next
+       // stage of data copying
+       if ( (oldData = oldData[ internalKey ]) ) {
+               var events = oldData.events;
+                               curData = curData[ internalKey ] = jQuery.extend({}, oldData);
+
+               if ( events ) {
+                       delete curData.handle;
+                       curData.events = {};
+
+                       for ( var type in events ) {
+                               for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
+                                       jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
+                               }
+                       }
+               }
+       }
+}
+
+function cloneFixAttributes( src, dest ) {
+       var nodeName;
+
+       // We do not need to do anything for non-Elements
+       if ( dest.nodeType !== 1 ) {
+               return;
+       }
+
+       // clearAttributes removes the attributes, which we don't want,
+       // but also removes the attachEvent events, which we *do* want
+       if ( dest.clearAttributes ) {
+               dest.clearAttributes();
+       }
+
+       // mergeAttributes, in contrast, only merges back on the
+       // original attributes, not the events
+       if ( dest.mergeAttributes ) {
+               dest.mergeAttributes( src );
+       }
+
+       nodeName = dest.nodeName.toLowerCase();
+
+       // IE6-8 fail to clone children inside object elements that use
+       // the proprietary classid attribute value (rather than the type
+       // attribute) to identify the type of content to display
+       if ( nodeName === "object" ) {
+               dest.outerHTML = src.outerHTML;
+
+       } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
+               // IE6-8 fails to persist the checked state of a cloned checkbox
+               // or radio button. Worse, IE6-7 fail to give the cloned element
+               // a checked appearance if the defaultChecked value isn't also set
+               if ( src.checked ) {
+                       dest.defaultChecked = dest.checked = src.checked;
+               }
+
+               // IE6-7 get confused and end up setting the value of a cloned
+               // checkbox/radio button to an empty string instead of "on"
+               if ( dest.value !== src.value ) {
+                       dest.value = src.value;
+               }
+
+       // IE6-8 fails to return the selected option to the default selected
+       // state when cloning options
+       } else if ( nodeName === "option" ) {
+               dest.selected = src.defaultSelected;
+
+       // IE6-8 fails to set the defaultValue to the correct value when
+       // cloning other types of input fields
+       } else if ( nodeName === "input" || nodeName === "textarea" ) {
+               dest.defaultValue = src.defaultValue;
+       }
+
+       // Event data gets referenced instead of copied if the expando
+       // gets copied too
+       dest.removeAttribute( jQuery.expando );
+}
+
+jQuery.buildFragment = function( args, nodes, scripts ) {
+       var fragment, cacheable, cacheresults,
+               doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+
+       // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
+       // Cloning options loses the selected state, so don't cache them
+       // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+       // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+       if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+               args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+
+               cacheable = true;
+
+               cacheresults = jQuery.fragments[ args[0] ];
+               if ( cacheresults && cacheresults !== 1 ) {
+                       fragment = cacheresults;
+               }
+       }
+
+       if ( !fragment ) {
+               fragment = doc.createDocumentFragment();
+               jQuery.clean( args, doc, fragment, scripts );
+       }
+
+       if ( cacheable ) {
+               jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+       }
+
+       return { fragment: fragment, cacheable: cacheable };
+};
+
+jQuery.fragments = {};
+
+jQuery.each({
+       appendTo: "append",
+       prependTo: "prepend",
+       insertBefore: "before",
+       insertAfter: "after",
+       replaceAll: "replaceWith"
+}, function( name, original ) {
+       jQuery.fn[ name ] = function( selector ) {
+               var ret = [],
+                       insert = jQuery( selector ),
+                       parent = this.length === 1 && this[0].parentNode;
+
+               if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+                       insert[ original ]( this[0] );
+                       return this;
+
+               } else {
+                       for ( var i = 0, l = insert.length; i < l; i++ ) {
+                               var elems = (i > 0 ? this.clone(true) : this).get();
+                               jQuery( insert[i] )[ original ]( elems );
+                               ret = ret.concat( elems );
+                       }
+
+                       return this.pushStack( ret, name, insert.selector );
+               }
+       };
+});
+
+function getAll( elem ) {
+       if ( "getElementsByTagName" in elem ) {
+               return elem.getElementsByTagName( "*" );
+       
+       } else if ( "querySelectorAll" in elem ) {
+               return elem.querySelectorAll( "*" );
+
+       } else {
+               return [];
+       }
+}
+
+// Used in clean, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+       if ( elem.type === "checkbox" || elem.type === "radio" ) {
+               elem.defaultChecked = elem.checked;
+       }
+}
+// Finds all inputs and passes them to fixDefaultChecked
+function findInputs( elem ) {
+       if ( jQuery.nodeName( elem, "input" ) ) {
+               fixDefaultChecked( elem );
+       } else if ( elem.getElementsByTagName ) {
+               jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
+       }
+}
+
+jQuery.extend({
+       clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+               var clone = elem.cloneNode(true),
+                               srcElements,
+                               destElements,
+                               i;
+
+               if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+                               (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+                       // IE copies events bound via attachEvent when using cloneNode.
+                       // Calling detachEvent on the clone will also remove the events
+                       // from the original. In order to get around this, we use some
+                       // proprietary methods to clear the events. Thanks to MooTools
+                       // guys for this hotness.
+
+                       cloneFixAttributes( elem, clone );
+
+                       // Using Sizzle here is crazy slow, so we use getElementsByTagName
+                       // instead
+                       srcElements = getAll( elem );
+                       destElements = getAll( clone );
+
+                       // Weird iteration because IE will replace the length property
+                       // with an element if you are cloning the body and one of the
+                       // elements on the page has a name or id of "length"
+                       for ( i = 0; srcElements[i]; ++i ) {
+                               cloneFixAttributes( srcElements[i], destElements[i] );
+                       }
+               }
+
+               // Copy the events from the original to the clone
+               if ( dataAndEvents ) {
+                       cloneCopyEvent( elem, clone );
+
+                       if ( deepDataAndEvents ) {
+                               srcElements = getAll( elem );
+                               destElements = getAll( clone );
+
+                               for ( i = 0; srcElements[i]; ++i ) {
+                                       cloneCopyEvent( srcElements[i], destElements[i] );
+                               }
+                       }
+               }
+
+               // Return the cloned set
+               return clone;
+       },
+
+       clean: function( elems, context, fragment, scripts ) {
+               var checkScriptType;
+
+               context = context || document;
+
+               // !context.createElement fails in IE with an error but returns typeof 'object'
+               if ( typeof context.createElement === "undefined" ) {
+                       context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+               }
+
+               var ret = [];
+
+               for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+                       if ( typeof elem === "number" ) {
+                               elem += "";
+                       }
+
+                       if ( !elem ) {
+                               continue;
+                       }
+
+                       // Convert html string into DOM nodes
+                       if ( typeof elem === "string" ) {
+                               if ( !rhtml.test( elem ) ) {
+                                       elem = context.createTextNode( elem );
+                               } else {
+                                       // Fix "XHTML"-style tags in all browsers
+                                       elem = elem.replace(rxhtmlTag, "<$1></$2>");
+
+                                       // Trim whitespace, otherwise indexOf won't work as expected
+                                       var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+                                               wrap = wrapMap[ tag ] || wrapMap._default,
+                                               depth = wrap[0],
+                                               div = context.createElement("div");
+
+                                       // Go to html and back, then peel off extra wrappers
+                                       div.innerHTML = wrap[1] + elem + wrap[2];
+
+                                       // Move to the right depth
+                                       while ( depth-- ) {
+                                               div = div.lastChild;
+                                       }
+
+                                       // Remove IE's autoinserted <tbody> from table fragments
+                                       if ( !jQuery.support.tbody ) {
+
+                                               // String was a <table>, *may* have spurious <tbody>
+                                               var hasBody = rtbody.test(elem),
+                                                       tbody = tag === "table" && !hasBody ?
+                                                               div.firstChild && div.firstChild.childNodes :
+
+                                                               // String was a bare <thead> or <tfoot>
+                                                               wrap[1] === "<table>" && !hasBody ?
+                                                                       div.childNodes :
+                                                                       [];
+
+                                               for ( var j = tbody.length - 1; j >= 0 ; --j ) {
+                                                       if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+                                                               tbody[ j ].parentNode.removeChild( tbody[ j ] );
+                                                       }
+                                               }
+                                       }
+
+                                       // IE completely kills leading whitespace when innerHTML is used
+                                       if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+                                               div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+                                       }
+
+                                       elem = div.childNodes;
+                               }
+                       }
+
+                       // Resets defaultChecked for any radios and checkboxes
+                       // about to be appended to the DOM in IE 6/7 (#8060)
+                       var len;
+                       if ( !jQuery.support.appendChecked ) {
+                               if ( elem[0] && typeof (len = elem.length) === "number" ) {
+                                       for ( i = 0; i < len; i++ ) {
+                                               findInputs( elem[i] );
+                                       }
+                               } else {
+                                       findInputs( elem );
+                               }
+                       }
+
+                       if ( elem.nodeType ) {
+                               ret.push( elem );
+                       } else {
+                               ret = jQuery.merge( ret, elem );
+                       }
+               }
+
+               if ( fragment ) {
+                       checkScriptType = function( elem ) {
+                               return !elem.type || rscriptType.test( elem.type );
+                       };
+                       for ( i = 0; ret[i]; i++ ) {
+                               if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+                                       scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+
+                               } else {
+                                       if ( ret[i].nodeType === 1 ) {
+                                               var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
+
+                                               ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
+                                       }
+                                       fragment.appendChild( ret[i] );
+                               }
+                       }
+               }
+
+               return ret;
+       },
+
+       cleanData: function( elems ) {
+               var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
+                       deleteExpando = jQuery.support.deleteExpando;
+
+               for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+                       if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+                               continue;
+                       }
+
+                       id = elem[ jQuery.expando ];
+
+                       if ( id ) {
+                               data = cache[ id ] && cache[ id ][ internalKey ];
+
+                               if ( data && data.events ) {
+                                       for ( var type in data.events ) {
+                                               if ( special[ type ] ) {
+                                                       jQuery.event.remove( elem, type );
+
+                                               // This is a shortcut to avoid jQuery.event.remove's overhead
+                                               } else {
+                                                       jQuery.removeEvent( elem, type, data.handle );
+                                               }
+                                       }
+
+                                       // Null the DOM reference to avoid IE6/7/8 leak (#7054)
+                                       if ( data.handle ) {
+                                               data.handle.elem = null;
+                                       }
+                               }
+
+                               if ( deleteExpando ) {
+                                       delete elem[ jQuery.expando ];
+
+                               } else if ( elem.removeAttribute ) {
+                                       elem.removeAttribute( jQuery.expando );
+                               }
+
+                               delete cache[ id ];
+                       }
+               }
+       }
+});
+
+function evalScript( i, elem ) {
+       if ( elem.src ) {
+               jQuery.ajax({
+                       url: elem.src,
+                       async: false,
+                       dataType: "script"
+               });
+       } else {
+               jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+       }
+
+       if ( elem.parentNode ) {
+               elem.parentNode.removeChild( elem );
+       }
+}
+
+
+
+
+var ralpha = /alpha\([^)]*\)/i,
+       ropacity = /opacity=([^)]*)/,
+       rdashAlpha = /-([a-z])/ig,
+       // fixed for IE9, see #8346
+       rupper = /([A-Z]|^ms)/g,
+       rnumpx = /^-?\d+(?:px)?$/i,
+       rnum = /^-?\d/,
+       rrelNum = /^[+\-]=/,
+       rrelNumFilter = /[^+\-\.\de]+/g,
+
+       cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+       cssWidth = [ "Left", "Right" ],
+       cssHeight = [ "Top", "Bottom" ],
+       curCSS,
+
+       getComputedStyle,
+       currentStyle,
+
+       fcamelCase = function( all, letter ) {
+               return letter.toUpperCase();
+       };
+
+jQuery.fn.css = function( name, value ) {
+       // Setting 'undefined' is a no-op
+       if ( arguments.length === 2 && value === undefined ) {
+               return this;
+       }
+
+       return jQuery.access( this, name, value, true, function( elem, name, value ) {
+               return value !== undefined ?
+                       jQuery.style( elem, name, value ) :
+                       jQuery.css( elem, name );
+       });
+};
+
+jQuery.extend({
+       // Add in style property hooks for overriding the default
+       // behavior of getting and setting a style property
+       cssHooks: {
+               opacity: {
+                       get: function( elem, computed ) {
+                               if ( computed ) {
+                                       // We should always get a number back from opacity
+                                       var ret = curCSS( elem, "opacity", "opacity" );
+                                       return ret === "" ? "1" : ret;
+
+                               } else {
+                                       return elem.style.opacity;
+                               }
+                       }
+               }
+       },
+
+       // Exclude the following css properties to add px
+       cssNumber: {
+               "zIndex": true,
+               "fontWeight": true,
+               "opacity": true,
+               "zoom": true,
+               "lineHeight": true,
+               "widows": true,
+               "orphans": true
+       },
+
+       // Add in properties whose names you wish to fix before
+       // setting or getting the value
+       cssProps: {
+               // normalize float css property
+               "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+       },
+
+       // Get and set the style property on a DOM Node
+       style: function( elem, name, value, extra ) {
+               // Don't set styles on text and comment nodes
+               if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+                       return;
+               }
+
+               // Make sure that we're working with the right name
+               var ret, type, origName = jQuery.camelCase( name ),
+                       style = elem.style, hooks = jQuery.cssHooks[ origName ];
+
+               name = jQuery.cssProps[ origName ] || origName;
+
+               // Check if we're setting a value
+               if ( value !== undefined ) {
+                       type = typeof value;
+
+                       // Make sure that NaN and null values aren't set. See: #7116
+                       if ( type === "number" && isNaN( value ) || value == null ) {
+                               return;
+                       }
+
+                       // convert relative number strings (+= or -=) to relative numbers. #7345
+                       if ( type === "string" && rrelNum.test( value ) ) {
+                               value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
+                       }
+
+                       // If a number was passed in, add 'px' to the (except for certain CSS properties)
+                       if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+                               value += "px";
+                       }
+
+                       // If a hook was provided, use that value, otherwise just set the specified value
+                       if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
+                               // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+                               // Fixes bug #5509
+                               try {
+                                       style[ name ] = value;
+                               } catch(e) {}
+                       }
+
+               } else {
+                       // If a hook was provided get the non-computed value from there
+                       if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+                               return ret;
+                       }
+
+                       // Otherwise just get the value from the style object
+                       return style[ name ];
+               }
+       },
+
+       css: function( elem, name, extra ) {
+               var ret, hooks;
+
+               // Make sure that we're working with the right name
+               name = jQuery.camelCase( name );
+               hooks = jQuery.cssHooks[ name ];
+               name = jQuery.cssProps[ name ] || name;
+
+               // cssFloat needs a special treatment
+               if ( name === "cssFloat" ) {
+                       name = "float";
+               }
+
+               // If a hook was provided get the computed value from there
+               if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
+                       return ret;
+
+               // Otherwise, if a way to get the computed value exists, use that
+               } else if ( curCSS ) {
+                       return curCSS( elem, name );
+               }
+       },
+
+       // A method for quickly swapping in/out CSS properties to get correct calculations
+       swap: function( elem, options, callback ) {
+               var old = {};
+
+               // Remember the old values, and insert the new ones
+               for ( var name in options ) {
+                       old[ name ] = elem.style[ name ];
+                       elem.style[ name ] = options[ name ];
+               }
+
+               callback.call( elem );
+
+               // Revert the old values
+               for ( name in options ) {
+                       elem.style[ name ] = old[ name ];
+               }
+       },
+
+       camelCase: function( string ) {
+               return string.replace( rdashAlpha, fcamelCase );
+       }
+});
+
+// DEPRECATED, Use jQuery.css() instead
+jQuery.curCSS = jQuery.css;
+
+jQuery.each(["height", "width"], function( i, name ) {
+       jQuery.cssHooks[ name ] = {
+               get: function( elem, computed, extra ) {
+                       var val;
+
+                       if ( computed ) {
+                               if ( elem.offsetWidth !== 0 ) {
+                                       val = getWH( elem, name, extra );
+
+                               } else {
+                                       jQuery.swap( elem, cssShow, function() {
+                                               val = getWH( elem, name, extra );
+                                       });
+                               }
+
+                               if ( val <= 0 ) {
+                                       val = curCSS( elem, name, name );
+
+                                       if ( val === "0px" && currentStyle ) {
+                                               val = currentStyle( elem, name, name );
+                                       }
+
+                                       if ( val != null ) {
+                                               // Should return "auto" instead of 0, use 0 for
+                                               // temporary backwards-compat
+                                               return val === "" || val === "auto" ? "0px" : val;
+                                       }
+                               }
+
+                               if ( val < 0 || val == null ) {
+                                       val = elem.style[ name ];
+
+                                       // Should return "auto" instead of 0, use 0 for
+                                       // temporary backwards-compat
+                                       return val === "" || val === "auto" ? "0px" : val;
+                               }
+
+                               return typeof val === "string" ? val : val + "px";
+                       }
+               },
+
+               set: function( elem, value ) {
+                       if ( rnumpx.test( value ) ) {
+                               // ignore negative width and height values #1599
+                               value = parseFloat(value);
+
+                               if ( value >= 0 ) {
+                                       return value + "px";
+                               }
+
+                       } else {
+                               return value;
+                       }
+               }
+       };
+});
+
+if ( !jQuery.support.opacity ) {
+       jQuery.cssHooks.opacity = {
+               get: function( elem, computed ) {
+                       // IE uses filters for opacity
+                       return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+                               ( parseFloat( RegExp.$1 ) / 100 ) + "" :
+                               computed ? "1" : "";
+               },
+
+               set: function( elem, value ) {
+                       var style = elem.style,
+                               currentStyle = elem.currentStyle;
+
+                       // IE has trouble with opacity if it does not have layout
+                       // Force it by setting the zoom level
+                       style.zoom = 1;
+
+                       // Set the alpha filter to set the opacity
+                       var opacity = jQuery.isNaN( value ) ?
+                               "" :
+                               "alpha(opacity=" + value * 100 + ")",
+                               filter = currentStyle && currentStyle.filter || style.filter || "";
+
+                       style.filter = ralpha.test( filter ) ?
+                               filter.replace( ralpha, opacity ) :
+                               filter + " " + opacity;
+               }
+       };
+}
+
+jQuery(function() {
+       // This hook cannot be added until DOM ready because the support test
+       // for it is not run until after DOM ready
+       if ( !jQuery.support.reliableMarginRight ) {
+               jQuery.cssHooks.marginRight = {
+                       get: function( elem, computed ) {
+                               // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+                               // Work around by temporarily setting element display to inline-block
+                               var ret;
+                               jQuery.swap( elem, { "display": "inline-block" }, function() {
+                                       if ( computed ) {
+                                               ret = curCSS( elem, "margin-right", "marginRight" );
+                                       } else {
+                                               ret = elem.style.marginRight;
+                                       }
+                               });
+                               return ret;
+                       }
+               };
+       }
+});
+
+if ( document.defaultView && document.defaultView.getComputedStyle ) {
+       getComputedStyle = function( elem, name ) {
+               var ret, defaultView, computedStyle;
+
+               name = name.replace( rupper, "-$1" ).toLowerCase();
+
+               if ( !(defaultView = elem.ownerDocument.defaultView) ) {
+                       return undefined;
+               }
+
+               if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
+                       ret = computedStyle.getPropertyValue( name );
+                       if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
+                               ret = jQuery.style( elem, name );
+                       }
+               }
+
+               return ret;
+       };
+}
+
+if ( document.documentElement.currentStyle ) {
+       currentStyle = function( elem, name ) {
+               var left,
+                       ret = elem.currentStyle && elem.currentStyle[ name ],
+                       rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
+                       style = elem.style;
+
+               // From the awesome hack by Dean Edwards
+               // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+               // If we're not dealing with a regular pixel number
+               // but a number that has a weird ending, we need to convert it to pixels
+               if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+                       // Remember the original values
+                       left = style.left;
+
+                       // Put in the new values to get a computed value out
+                       if ( rsLeft ) {
+                               elem.runtimeStyle.left = elem.currentStyle.left;
+                       }
+                       style.left = name === "fontSize" ? "1em" : (ret || 0);
+                       ret = style.pixelLeft + "px";
+
+                       // Revert the changed values
+                       style.left = left;
+                       if ( rsLeft ) {
+                               elem.runtimeStyle.left = rsLeft;
+                       }
+               }
+
+               return ret === "" ? "auto" : ret;
+       };
+}
+
+curCSS = getComputedStyle || currentStyle;
+
+function getWH( elem, name, extra ) {
+       var which = name === "width" ? cssWidth : cssHeight,
+               val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
+
+       if ( extra === "border" ) {
+               return val;
+       }
+
+       jQuery.each( which, function() {
+               if ( !extra ) {
+                       val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
+               }
+
+               if ( extra === "margin" ) {
+                       val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
+
+               } else {
+                       val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
+               }
+       });
+
+       return val;
+}
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+       jQuery.expr.filters.hidden = function( elem ) {
+               var width = elem.offsetWidth,
+                       height = elem.offsetHeight;
+
+               return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
+       };
+
+       jQuery.expr.filters.visible = function( elem ) {
+               return !jQuery.expr.filters.hidden( elem );
+       };
+}
+
+
+
+
+var r20 = /%20/g,
+       rbracket = /\[\]$/,
+       rCRLF = /\r?\n/g,
+       rhash = /#.*$/,
+       rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+       rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+       // #7653, #8125, #8152: local protocol detection
+       rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
+       rnoContent = /^(?:GET|HEAD)$/,
+       rprotocol = /^\/\//,
+       rquery = /\?/,
+       rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+       rselectTextarea = /^(?:select|textarea)/i,
+       rspacesAjax = /\s+/,
+       rts = /([?&])_=[^&]*/,
+       rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
+
+       // Keep a copy of the old load method
+       _load = jQuery.fn.load,
+
+       /* Prefilters
+        * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+        * 2) These are called:
+        *    - BEFORE asking for a transport
+        *    - AFTER param serialization (s.data is a string if s.processData is true)
+        * 3) key is the dataType
+        * 4) the catchall symbol "*" can be used
+        * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+        */
+       prefilters = {},
+
+       /* Transports bindings
+        * 1) key is the dataType
+        * 2) the catchall symbol "*" can be used
+        * 3) selection will start with transport dataType and THEN go to "*" if needed
+        */
+       transports = {},
+
+       // Document location
+       ajaxLocation,
+
+       // Document location segments
+       ajaxLocParts;
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+       ajaxLocation = location.href;
+} catch( e ) {
+       // Use the href attribute of an A element
+       // since IE will modify it given document.location
+       ajaxLocation = document.createElement( "a" );
+       ajaxLocation.href = "";
+       ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+       // dataTypeExpression is optional and defaults to "*"
+       return function( dataTypeExpression, func ) {
+
+               if ( typeof dataTypeExpression !== "string" ) {
+                       func = dataTypeExpression;
+                       dataTypeExpression = "*";
+               }
+
+               if ( jQuery.isFunction( func ) ) {
+                       var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
+                               i = 0,
+                               length = dataTypes.length,
+                               dataType,
+                               list,
+                               placeBefore;
+
+                       // For each dataType in the dataTypeExpression
+                       for(; i < length; i++ ) {
+                               dataType = dataTypes[ i ];
+                               // We control if we're asked to add before
+                               // any existing element
+                               placeBefore = /^\+/.test( dataType );
+                               if ( placeBefore ) {
+                                       dataType = dataType.substr( 1 ) || "*";
+                               }
+                               list = structure[ dataType ] = structure[ dataType ] || [];
+                               // then we add to the structure accordingly
+                               list[ placeBefore ? "unshift" : "push" ]( func );
+                       }
+               }
+       };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
+               dataType /* internal */, inspected /* internal */ ) {
+
+       dataType = dataType || options.dataTypes[ 0 ];
+       inspected = inspected || {};
+
+       inspected[ dataType ] = true;
+
+       var list = structure[ dataType ],
+               i = 0,
+               length = list ? list.length : 0,
+               executeOnly = ( structure === prefilters ),
+               selection;
+
+       for(; i < length && ( executeOnly || !selection ); i++ ) {
+               selection = list[ i ]( options, originalOptions, jqXHR );
+               // If we got redirected to another dataType
+               // we try there if executing only and not done already
+               if ( typeof selection === "string" ) {
+                       if ( !executeOnly || inspected[ selection ] ) {
+                               selection = undefined;
+                       } else {
+                               options.dataTypes.unshift( selection );
+                               selection = inspectPrefiltersOrTransports(
+                                               structure, options, originalOptions, jqXHR, selection, inspected );
+                       }
+               }
+       }
+       // If we're only executing or nothing was selected
+       // we try the catchall dataType if not done already
+       if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
+               selection = inspectPrefiltersOrTransports(
+                               structure, options, originalOptions, jqXHR, "*", inspected );
+       }
+       // unnecessary when only executing (prefilters)
+       // but it'll be ignored by the caller in that case
+       return selection;
+}
+
+jQuery.fn.extend({
+       load: function( url, params, callback ) {
+               if ( typeof url !== "string" && _load ) {
+                       return _load.apply( this, arguments );
+
+               // Don't do a request if no elements are being requested
+               } else if ( !this.length ) {
+                       return this;
+               }
+
+               var off = url.indexOf( " " );
+               if ( off >= 0 ) {
+                       var selector = url.slice( off, url.length );
+                       url = url.slice( 0, off );
+               }
+
+               // Default to a GET request
+               var type = "GET";
+
+               // If the second parameter was provided
+               if ( params ) {
+                       // If it's a function
+                       if ( jQuery.isFunction( params ) ) {
+                               // We assume that it's the callback
+                               callback = params;
+                               params = undefined;
+
+                       // Otherwise, build a param string
+                       } else if ( typeof params === "object" ) {
+                               params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+                               type = "POST";
+                       }
+               }
+
+               var self = this;
+
+               // Request the remote document
+               jQuery.ajax({
+                       url: url,
+                       type: type,
+                       dataType: "html",
+                       data: params,
+                       // Complete callback (responseText is used internally)
+                       complete: function( jqXHR, status, responseText ) {
+                               // Store the response as specified by the jqXHR object
+                               responseText = jqXHR.responseText;
+                               // If successful, inject the HTML into all the matched elements
+                               if ( jqXHR.isResolved() ) {
+                                       // #4825: Get the actual response in case
+                                       // a dataFilter is present in ajaxSettings
+                                       jqXHR.done(function( r ) {
+                                               responseText = r;
+                                       });
+                                       // See if a selector was specified
+                                       self.html( selector ?
+                                               // Create a dummy div to hold the results
+                                               jQuery("<div>")
+                                                       // inject the contents of the document in, removing the scripts
+                                                       // to avoid any 'Permission Denied' errors in IE
+                                                       .append(responseText.replace(rscript, ""))
+
+                                                       // Locate the specified elements
+                                                       .find(selector) :
+
+                                               // If not, just inject the full result
+                                               responseText );
+                               }
+
+                               if ( callback ) {
+                                       self.each( callback, [ responseText, status, jqXHR ] );
+                               }
+                       }
+               });
+
+               return this;
+       },
+
+       serialize: function() {
+               return jQuery.param( this.serializeArray() );
+       },
+
+       serializeArray: function() {
+               return this.map(function(){
+                       return this.elements ? jQuery.makeArray( this.elements ) : this;
+               })
+               .filter(function(){
+                       return this.name && !this.disabled &&
+                               ( this.checked || rselectTextarea.test( this.nodeName ) ||
+                                       rinput.test( this.type ) );
+               })
+               .map(function( i, elem ){
+                       var val = jQuery( this ).val();
+
+                       return val == null ?
+                               null :
+                               jQuery.isArray( val ) ?
+                                       jQuery.map( val, function( val, i ){
+                                               return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+                                       }) :
+                                       { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+               }).get();
+       }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
+       jQuery.fn[ o ] = function( f ){
+               return this.bind( o, f );
+       };
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+       jQuery[ method ] = function( url, data, callback, type ) {
+               // shift arguments if data argument was omitted
+               if ( jQuery.isFunction( data ) ) {
+                       type = type || callback;
+                       callback = data;
+                       data = undefined;
+               }
+
+               return jQuery.ajax({
+                       type: method,
+                       url: url,
+                       data: data,
+                       success: callback,
+                       dataType: type
+               });
+       };
+});
+
+jQuery.extend({
+
+       getScript: function( url, callback ) {
+               return jQuery.get( url, undefined, callback, "script" );
+       },
+
+       getJSON: function( url, data, callback ) {
+               return jQuery.get( url, data, callback, "json" );
+       },
+
+       // Creates a full fledged settings object into target
+       // with both ajaxSettings and settings fields.
+       // If target is omitted, writes into ajaxSettings.
+       ajaxSetup: function ( target, settings ) {
+               if ( !settings ) {
+                       // Only one parameter, we extend ajaxSettings
+                       settings = target;
+                       target = jQuery.extend( true, jQuery.ajaxSettings, settings );
+               } else {
+                       // target was provided, we extend into it
+                       jQuery.extend( true, target, jQuery.ajaxSettings, settings );
+               }
+               // Flatten fields we don't want deep extended
+               for( var field in { context: 1, url: 1 } ) {
+                       if ( field in settings ) {
+                               target[ field ] = settings[ field ];
+                       } else if( field in jQuery.ajaxSettings ) {
+                               target[ field ] = jQuery.ajaxSettings[ field ];
+                       }
+               }
+               return target;
+       },
+
+       ajaxSettings: {
+               url: ajaxLocation,
+               isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+               global: true,
+               type: "GET",
+               contentType: "application/x-www-form-urlencoded",
+               processData: true,
+               async: true,
+               /*
+               timeout: 0,
+               data: null,
+               dataType: null,
+               username: null,
+               password: null,
+               cache: null,
+               traditional: false,
+               headers: {},
+               */
+
+               accepts: {
+                       xml: "application/xml, text/xml",
+                       html: "text/html",
+                       text: "text/plain",
+                       json: "application/json, text/javascript",
+                       "*": "*/*"
+               },
+
+               contents: {
+                       xml: /xml/,
+                       html: /html/,
+                       json: /json/
+               },
+
+               responseFields: {
+                       xml: "responseXML",
+                       text: "responseText"
+               },
+
+               // List of data converters
+               // 1) key format is "source_type destination_type" (a single space in-between)
+               // 2) the catchall symbol "*" can be used for source_type
+               converters: {
+
+                       // Convert anything to text
+                       "* text": window.String,
+
+                       // Text to html (true = no transformation)
+                       "text html": true,
+
+                       // Evaluate text as a json expression
+                       "text json": jQuery.parseJSON,
+
+                       // Parse text as xml
+                       "text xml": jQuery.parseXML
+               }
+       },
+
+       ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+       ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+       // Main method
+       ajax: function( url, options ) {
+
+               // If url is an object, simulate pre-1.5 signature
+               if ( typeof url === "object" ) {
+                       options = url;
+                       url = undefined;
+               }
+
+               // Force options to be an object
+               options = options || {};
+
+               var // Create the final options object
+                       s = jQuery.ajaxSetup( {}, options ),
+                       // Callbacks context
+                       callbackContext = s.context || s,
+                       // Context for global events
+                       // It's the callbackContext if one was provided in the options
+                       // and if it's a DOM node or a jQuery collection
+                       globalEventContext = callbackContext !== s &&
+                               ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
+                                               jQuery( callbackContext ) : jQuery.event,
+                       // Deferreds
+                       deferred = jQuery.Deferred(),
+                       completeDeferred = jQuery._Deferred(),
+                       // Status-dependent callbacks
+                       statusCode = s.statusCode || {},
+                       // ifModified key
+                       ifModifiedKey,
+                       // Headers (they are sent all at once)
+                       requestHeaders = {},
+                       requestHeadersNames = {},
+                       // Response headers
+                       responseHeadersString,
+                       responseHeaders,
+                       // transport
+                       transport,
+                       // timeout handle
+                       timeoutTimer,
+                       // Cross-domain detection vars
+                       parts,
+                       // The jqXHR state
+                       state = 0,
+                       // To know if global events are to be dispatched
+                       fireGlobals,
+                       // Loop variable
+                       i,
+                       // Fake xhr
+                       jqXHR = {
+
+                               readyState: 0,
+
+                               // Caches the header
+                               setRequestHeader: function( name, value ) {
+                                       if ( !state ) {
+                                               var lname = name.toLowerCase();
+                                               name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+                                               requestHeaders[ name ] = value;
+                                       }
+                                       return this;
+                               },
+
+                               // Raw string
+                               getAllResponseHeaders: function() {
+                                       return state === 2 ? responseHeadersString : null;
+                               },
+
+                               // Builds headers hashtable if needed
+                               getResponseHeader: function( key ) {
+                                       var match;
+                                       if ( state === 2 ) {
+                                               if ( !responseHeaders ) {
+                                                       responseHeaders = {};
+                                                       while( ( match = rheaders.exec( responseHeadersString ) ) ) {
+                                                               responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+                                                       }
+                                               }
+                                               match = responseHeaders[ key.toLowerCase() ];
+                                       }
+                                       return match === undefined ? null : match;
+                               },
+
+                               // Overrides response content-type header
+                               overrideMimeType: function( type ) {
+                                       if ( !state ) {
+                                               s.mimeType = type;
+                                       }
+                                       return this;
+                               },
+
+                               // Cancel the request
+                               abort: function( statusText ) {
+                                       statusText = statusText || "abort";
+                                       if ( transport ) {
+                                               transport.abort( statusText );
+                                       }
+                                       done( 0, statusText );
+                                       return this;
+                               }
+                       };
+
+               // Callback for when everything is done
+               // It is defined here because jslint complains if it is declared
+               // at the end of the function (which would be more logical and readable)
+               function done( status, statusText, responses, headers ) {
+
+                       // Called once
+                       if ( state === 2 ) {
+                               return;
+                       }
+
+                       // State is "done" now
+                       state = 2;
+
+                       // Clear timeout if it exists
+                       if ( timeoutTimer ) {
+                               clearTimeout( timeoutTimer );
+                       }
+
+                       // Dereference transport for early garbage collection
+                       // (no matter how long the jqXHR object will be used)
+                       transport = undefined;
+
+                       // Cache response headers
+                       responseHeadersString = headers || "";
+
+                       // Set readyState
+                       jqXHR.readyState = status ? 4 : 0;
+
+                       var isSuccess,
+                               success,
+                               error,
+                               response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
+                               lastModified,
+                               etag;
+
+                       // If successful, handle type chaining
+                       if ( status >= 200 && status < 300 || status === 304 ) {
+
+                               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+                               if ( s.ifModified ) {
+
+                                       if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
+                                               jQuery.lastModified[ ifModifiedKey ] = lastModified;
+                                       }
+                                       if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
+                                               jQuery.etag[ ifModifiedKey ] = etag;
+                                       }
+                               }
+
+                               // If not modified
+                               if ( status === 304 ) {
+
+                                       statusText = "notmodified";
+                                       isSuccess = true;
+
+                               // If we have data
+                               } else {
+
+                                       try {
+                                               success = ajaxConvert( s, response );
+                                               statusText = "success";
+                                               isSuccess = true;
+                                       } catch(e) {
+                                               // We have a parsererror
+                                               statusText = "parsererror";
+                                               error = e;
+                                       }
+                               }
+                       } else {
+                               // We extract error from statusText
+                               // then normalize statusText and status for non-aborts
+                               error = statusText;
+                               if( !statusText || status ) {
+                                       statusText = "error";
+                                       if ( status < 0 ) {
+                                               status = 0;
+                                       }
+                               }
+                       }
+
+                       // Set data for the fake xhr object
+                       jqXHR.status = status;
+                       jqXHR.statusText = statusText;
+
+                       // Success/Error
+                       if ( isSuccess ) {
+                               deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+                       } else {
+                               deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+                       }
+
+                       // Status-dependent callbacks
+                       jqXHR.statusCode( statusCode );
+                       statusCode = undefined;
+
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
+                                               [ jqXHR, s, isSuccess ? success : error ] );
+                       }
+
+                       // Complete
+                       completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
+
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
+                               // Handle the global AJAX counter
+                               if ( !( --jQuery.active ) ) {
+                                       jQuery.event.trigger( "ajaxStop" );
+                               }
+                       }
+               }
+
+               // Attach deferreds
+               deferred.promise( jqXHR );
+               jqXHR.success = jqXHR.done;
+               jqXHR.error = jqXHR.fail;
+               jqXHR.complete = completeDeferred.done;
+
+               // Status-dependent callbacks
+               jqXHR.statusCode = function( map ) {
+                       if ( map ) {
+                               var tmp;
+                               if ( state < 2 ) {
+                                       for( tmp in map ) {
+                                               statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
+                                       }
+                               } else {
+                                       tmp = map[ jqXHR.status ];
+                                       jqXHR.then( tmp, tmp );
+                               }
+                       }
+                       return this;
+               };
+
+               // Remove hash character (#7531: and string promotion)
+               // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+               // We also use the url parameter if available
+               s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+               // Extract dataTypes list
+               s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
+
+               // Determine if a cross-domain request is in order
+               if ( s.crossDomain == null ) {
+                       parts = rurl.exec( s.url.toLowerCase() );
+                       s.crossDomain = !!( parts &&
+                               ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
+                                       ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
+                                               ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
+                       );
+               }
+
+               // Convert data if not already a string
+               if ( s.data && s.processData && typeof s.data !== "string" ) {
+                       s.data = jQuery.param( s.data, s.traditional );
+               }
+
+               // Apply prefilters
+               inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+               // If request was aborted inside a prefiler, stop there
+               if ( state === 2 ) {
+                       return false;
+               }
+
+               // We can fire global events as of now if asked to
+               fireGlobals = s.global;
+
+               // Uppercase the type
+               s.type = s.type.toUpperCase();
+
+               // Determine if request has content
+               s.hasContent = !rnoContent.test( s.type );
+
+               // Watch for a new set of requests
+               if ( fireGlobals && jQuery.active++ === 0 ) {
+                       jQuery.event.trigger( "ajaxStart" );
+               }
+
+               // More options handling for requests with no content
+               if ( !s.hasContent ) {
+
+                       // If data is available, append data to url
+                       if ( s.data ) {
+                               s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
+                       }
+
+                       // Get ifModifiedKey before adding the anti-cache parameter
+                       ifModifiedKey = s.url;
+
+                       // Add anti-cache in url if needed
+                       if ( s.cache === false ) {
+
+                               var ts = jQuery.now(),
+                                       // try replacing _= if it is there
+                                       ret = s.url.replace( rts, "$1_=" + ts );
+
+                               // if nothing was replaced, add timestamp to the end
+                               s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
+                       }
+               }
+
+               // Set the correct header, if data is being sent
+               if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+                       jqXHR.setRequestHeader( "Content-Type", s.contentType );
+               }
+
+               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+               if ( s.ifModified ) {
+                       ifModifiedKey = ifModifiedKey || s.url;
+                       if ( jQuery.lastModified[ ifModifiedKey ] ) {
+                               jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
+                       }
+                       if ( jQuery.etag[ ifModifiedKey ] ) {
+                               jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
+                       }
+               }
+
+               // Set the Accepts header for the server, depending on the dataType
+               jqXHR.setRequestHeader(
+                       "Accept",
+                       s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+                               s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
+                               s.accepts[ "*" ]
+               );
+
+               // Check for headers option
+               for ( i in s.headers ) {
+                       jqXHR.setRequestHeader( i, s.headers[ i ] );
+               }
+
+               // Allow custom headers/mimetypes and early abort
+               if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+                               // Abort if not done already
+                               jqXHR.abort();
+                               return false;
+
+               }
+
+               // Install callbacks on deferreds
+               for ( i in { success: 1, error: 1, complete: 1 } ) {
+                       jqXHR[ i ]( s[ i ] );
+               }
+
+               // Get transport
+               transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+               // If no transport, we auto-abort
+               if ( !transport ) {
+                       done( -1, "No Transport" );
+               } else {
+                       jqXHR.readyState = 1;
+                       // Send global event
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+                       }
+                       // Timeout
+                       if ( s.async && s.timeout > 0 ) {
+                               timeoutTimer = setTimeout( function(){
+                                       jqXHR.abort( "timeout" );
+                               }, s.timeout );
+                       }
+
+                       try {
+                               state = 1;
+                               transport.send( requestHeaders, done );
+                       } catch (e) {
+                               // Propagate exception as error if not done
+                               if ( status < 2 ) {
+                                       done( -1, e );
+                               // Simply rethrow otherwise
+                               } else {
+                                       jQuery.error( e );
+                               }
+                       }
+               }
+
+               return jqXHR;
+       },
+
+       // Serialize an array of form elements or a set of
+       // key/values into a query string
+       param: function( a, traditional ) {
+               var s = [],
+                       add = function( key, value ) {
+                               // If value is a function, invoke it and return its value
+                               value = jQuery.isFunction( value ) ? value() : value;
+                               s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+                       };
+
+               // Set traditional to true for jQuery <= 1.3.2 behavior.
+               if ( traditional === undefined ) {
+                       traditional = jQuery.ajaxSettings.traditional;
+               }
+
+               // If an array was passed in, assume that it is an array of form elements.
+               if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+                       // Serialize the form elements
+                       jQuery.each( a, function() {
+                               add( this.name, this.value );
+                       });
+
+               } else {
+                       // If traditional, encode the "old" way (the way 1.3.2 or older
+                       // did it), otherwise encode params recursively.
+                       for ( var prefix in a ) {
+                               buildParams( prefix, a[ prefix ], traditional, add );
+                       }
+               }
+
+               // Return the resulting serialization
+               return s.join( "&" ).replace( r20, "+" );
+       }
+});
+
+function buildParams( prefix, obj, traditional, add ) {
+       if ( jQuery.isArray( obj ) ) {
+               // Serialize array item.
+               jQuery.each( obj, function( i, v ) {
+                       if ( traditional || rbracket.test( prefix ) ) {
+                               // Treat each array item as a scalar.
+                               add( prefix, v );
+
+                       } else {
+                               // If array item is non-scalar (array or object), encode its
+                               // numeric index to resolve deserialization ambiguity issues.
+                               // Note that rack (as of 1.0.0) can't currently deserialize
+                               // nested arrays properly, and attempting to do so may cause
+                               // a server error. Possible fixes are to modify rack's
+                               // deserialization algorithm or to provide an option or flag
+                               // to force array serialization to be shallow.
+                               buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
+                       }
+               });
+
+       } else if ( !traditional && obj != null && typeof obj === "object" ) {
+               // Serialize object item.
+               for ( var name in obj ) {
+                       buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+               }
+
+       } else {
+               // Serialize scalar item.
+               add( prefix, obj );
+       }
+}
+
+// This is still on the jQuery object... for now
+// Want to move this to jQuery.ajax some day
+jQuery.extend({
+
+       // Counter for holding the number of active queries
+       active: 0,
+
+       // Last-Modified header cache for next request
+       lastModified: {},
+       etag: {}
+
+});
+
+/* Handles responses to an ajax request:
+ * - sets all responseXXX fields accordingly
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+
+       var contents = s.contents,
+               dataTypes = s.dataTypes,
+               responseFields = s.responseFields,
+               ct,
+               type,
+               finalDataType,
+               firstDataType;
+
+       // Fill responseXXX fields
+       for( type in responseFields ) {
+               if ( type in responses ) {
+                       jqXHR[ responseFields[type] ] = responses[ type ];
+               }
+       }
+
+       // Remove auto dataType and get content-type in the process
+       while( dataTypes[ 0 ] === "*" ) {
+               dataTypes.shift();
+               if ( ct === undefined ) {
+                       ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
+               }
+       }
+
+       // Check if we're dealing with a known content-type
+       if ( ct ) {
+               for ( type in contents ) {
+                       if ( contents[ type ] && contents[ type ].test( ct ) ) {
+                               dataTypes.unshift( type );
+                               break;
+                       }
+               }
+       }
+
+       // Check to see if we have a response for the expected dataType
+       if ( dataTypes[ 0 ] in responses ) {
+               finalDataType = dataTypes[ 0 ];
+       } else {
+               // Try convertible dataTypes
+               for ( type in responses ) {
+                       if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+                               finalDataType = type;
+                               break;
+                       }
+                       if ( !firstDataType ) {
+                               firstDataType = type;
+                       }
+               }
+               // Or just use first one
+               finalDataType = finalDataType || firstDataType;
+       }
+
+       // If we found a dataType
+       // We add the dataType to the list if needed
+       // and return the corresponding response
+       if ( finalDataType ) {
+               if ( finalDataType !== dataTypes[ 0 ] ) {
+                       dataTypes.unshift( finalDataType );
+               }
+               return responses[ finalDataType ];
+       }
+}
+
+// Chain conversions given the request and the original response
+function ajaxConvert( s, response ) {
+
+       // Apply the dataFilter if provided
+       if ( s.dataFilter ) {
+               response = s.dataFilter( response, s.dataType );
+       }
+
+       var dataTypes = s.dataTypes,
+               converters = {},
+               i,
+               key,
+               length = dataTypes.length,
+               tmp,
+               // Current and previous dataTypes
+               current = dataTypes[ 0 ],
+               prev,
+               // Conversion expression
+               conversion,
+               // Conversion function
+               conv,
+               // Conversion functions (transitive conversion)
+               conv1,
+               conv2;
+
+       // For each dataType in the chain
+       for( i = 1; i < length; i++ ) {
+
+               // Create converters map
+               // with lowercased keys
+               if ( i === 1 ) {
+                       for( key in s.converters ) {
+                               if( typeof key === "string" ) {
+                                       converters[ key.toLowerCase() ] = s.converters[ key ];
+                               }
+                       }
+               }
+
+               // Get the dataTypes
+               prev = current;
+               current = dataTypes[ i ];
+
+               // If current is auto dataType, update it to prev
+               if( current === "*" ) {
+                       current = prev;
+               // If no auto and dataTypes are actually different
+               } else if ( prev !== "*" && prev !== current ) {
+
+                       // Get the converter
+                       conversion = prev + " " + current;
+                       conv = converters[ conversion ] || converters[ "* " + current ];
+
+                       // If there is no direct converter, search transitively
+                       if ( !conv ) {
+                               conv2 = undefined;
+                               for( conv1 in converters ) {
+                                       tmp = conv1.split( " " );
+                                       if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
+                                               conv2 = converters[ tmp[1] + " " + current ];
+                                               if ( conv2 ) {
+                                                       conv1 = converters[ conv1 ];
+                                                       if ( conv1 === true ) {
+                                                               conv = conv2;
+                                                       } else if ( conv2 === true ) {
+                                                               conv = conv1;
+                                                       }
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       // If we found no converter, dispatch an error
+                       if ( !( conv || conv2 ) ) {
+                               jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
+                       }
+                       // If found converter is not an equivalence
+                       if ( conv !== true ) {
+                               // Convert with 1 or 2 converters accordingly
+                               response = conv ? conv( response ) : conv2( conv1(response) );
+                       }
+               }
+       }
+       return response;
+}
+
+
+
+
+var jsc = jQuery.now(),
+       jsre = /(\=)\?(&|$)|\?\?/i;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+       jsonp: "callback",
+       jsonpCallback: function() {
+               return jQuery.expando + "_" + ( jsc++ );
+       }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+       var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
+               ( typeof s.data === "string" );
+
+       if ( s.dataTypes[ 0 ] === "jsonp" ||
+               s.jsonp !== false && ( jsre.test( s.url ) ||
+                               inspectData && jsre.test( s.data ) ) ) {
+
+               var responseContainer,
+                       jsonpCallback = s.jsonpCallback =
+                               jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
+                       previous = window[ jsonpCallback ],
+                       url = s.url,
+                       data = s.data,
+                       replace = "$1" + jsonpCallback + "$2";
+
+               if ( s.jsonp !== false ) {
+                       url = url.replace( jsre, replace );
+                       if ( s.url === url ) {
+                               if ( inspectData ) {
+                                       data = data.replace( jsre, replace );
+                               }
+                               if ( s.data === data ) {
+                                       // Add callback manually
+                                       url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
+                               }
+                       }
+               }
+
+               s.url = url;
+               s.data = data;
+
+               // Install callback
+               window[ jsonpCallback ] = function( response ) {
+                       responseContainer = [ response ];
+               };
+
+               // Clean-up function
+               jqXHR.always(function() {
+                       // Set callback back to previous value
+                       window[ jsonpCallback ] = previous;
+                       // Call if it was a function and we have a response
+                       if ( responseContainer && jQuery.isFunction( previous ) ) {
+                               window[ jsonpCallback ]( responseContainer[ 0 ] );
+                       }
+               });
+
+               // Use data converter to retrieve json after script execution
+               s.converters["script json"] = function() {
+                       if ( !responseContainer ) {
+                               jQuery.error( jsonpCallback + " was not called" );
+                       }
+                       return responseContainer[ 0 ];
+               };
+
+               // force json dataType
+               s.dataTypes[ 0 ] = "json";
+
+               // Delegate to script
+               return "script";
+       }
+});
+
+
+
+
+// Install script dataType
+jQuery.ajaxSetup({
+       accepts: {
+               script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+       },
+       contents: {
+               script: /javascript|ecmascript/
+       },
+       converters: {
+               "text script": function( text ) {
+                       jQuery.globalEval( text );
+                       return text;
+               }
+       }
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+       if ( s.cache === undefined ) {
+               s.cache = false;
+       }
+       if ( s.crossDomain ) {
+               s.type = "GET";
+               s.global = false;
+       }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+       // This transport only deals with cross domain requests
+       if ( s.crossDomain ) {
+
+               var script,
+                       head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
+
+               return {
+
+                       send: function( _, callback ) {
+
+                               script = document.createElement( "script" );
+
+                               script.async = "async";
+
+                               if ( s.scriptCharset ) {
+                                       script.charset = s.scriptCharset;
+                               }
+
+                               script.src = s.url;
+
+                               // Attach handlers for all browsers
+                               script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+                                       if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+                                               // Handle memory leak in IE
+                                               script.onload = script.onreadystatechange = null;
+
+                                               // Remove the script
+                                               if ( head && script.parentNode ) {
+                                                       head.removeChild( script );
+                                               }
+
+                                               // Dereference the script
+                                               script = undefined;
+
+                                               // Callback if not abort
+                                               if ( !isAbort ) {
+                                                       callback( 200, "success" );
+                                               }
+                                       }
+                               };
+                               // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
+                               // This arises when a base node is used (#2709 and #4378).
+                               head.insertBefore( script, head.firstChild );
+                       },
+
+                       abort: function() {
+                               if ( script ) {
+                                       script.onload( 0, 1 );
+                               }
+                       }
+               };
+       }
+});
+
+
+
+
+var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+       xhrOnUnloadAbort = window.ActiveXObject ? function() {
+               // Abort all pending requests
+               for ( var key in xhrCallbacks ) {
+                       xhrCallbacks[ key ]( 0, 1 );
+               }
+       } : false,
+       xhrId = 0,
+       xhrCallbacks;
+
+// Functions to create xhrs
+function createStandardXHR() {
+       try {
+               return new window.XMLHttpRequest();
+       } catch( e ) {}
+}
+
+function createActiveXHR() {
+       try {
+               return new window.ActiveXObject( "Microsoft.XMLHTTP" );
+       } catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+       /* Microsoft failed to properly
+        * implement the XMLHttpRequest in IE7 (can't request local files),
+        * so we use the ActiveXObject when it is available
+        * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+        * we need a fallback.
+        */
+       function() {
+               return !this.isLocal && createStandardXHR() || createActiveXHR();
+       } :
+       // For all other browsers, use the standard XMLHttpRequest object
+       createStandardXHR;
+
+// Determine support properties
+(function( xhr ) {
+       jQuery.extend( jQuery.support, {
+               ajax: !!xhr,
+               cors: !!xhr && ( "withCredentials" in xhr )
+       });
+})( jQuery.ajaxSettings.xhr() );
+
+// Create transport if the browser can provide an xhr
+if ( jQuery.support.ajax ) {
+
+       jQuery.ajaxTransport(function( s ) {
+               // Cross domain only allowed if supported through XMLHttpRequest
+               if ( !s.crossDomain || jQuery.support.cors ) {
+
+                       var callback;
+
+                       return {
+                               send: function( headers, complete ) {
+
+                                       // Get a new xhr
+                                       var xhr = s.xhr(),
+                                               handle,
+                                               i;
+
+                                       // Open the socket
+                                       // Passing null username, generates a login popup on Opera (#2865)
+                                       if ( s.username ) {
+                                               xhr.open( s.type, s.url, s.async, s.username, s.password );
+                                       } else {
+                                               xhr.open( s.type, s.url, s.async );
+                                       }
+
+                                       // Apply custom fields if provided
+                                       if ( s.xhrFields ) {
+                                               for ( i in s.xhrFields ) {
+                                                       xhr[ i ] = s.xhrFields[ i ];
+                                               }
+                                       }
+
+                                       // Override mime type if needed
+                                       if ( s.mimeType && xhr.overrideMimeType ) {
+                                               xhr.overrideMimeType( s.mimeType );
+                                       }
+
+                                       // X-Requested-With header
+                                       // For cross-domain requests, seeing as conditions for a preflight are
+                                       // akin to a jigsaw puzzle, we simply never set it to be sure.
+                                       // (it can always be set on a per-request basis or even using ajaxSetup)
+                                       // For same-domain requests, won't change header if already provided.
+                                       if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+                                               headers[ "X-Requested-With" ] = "XMLHttpRequest";
+                                       }
+
+                                       // Need an extra try/catch for cross domain requests in Firefox 3
+                                       try {
+                                               for ( i in headers ) {
+                                                       xhr.setRequestHeader( i, headers[ i ] );
+                                               }
+                                       } catch( _ ) {}
+
+                                       // Do send the request
+                                       // This may raise an exception which is actually
+                                       // handled in jQuery.ajax (so no try/catch here)
+                                       xhr.send( ( s.hasContent && s.data ) || null );
+
+                                       // Listener
+                                       callback = function( _, isAbort ) {
+
+                                               var status,
+                                                       statusText,
+                                                       responseHeaders,
+                                                       responses,
+                                                       xml;
+
+                                               // Firefox throws exceptions when accessing properties
+                                               // of an xhr when a network error occured
+                                               // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+                                               try {
+
+                                                       // Was never called and is aborted or complete
+                                                       if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+                                                               // Only called once
+                                                               callback = undefined;
+
+                                                               // Do not keep as active anymore
+                                                               if ( handle ) {
+                                                                       xhr.onreadystatechange = jQuery.noop;
+                                                                       if ( xhrOnUnloadAbort ) {
+                                                                               delete xhrCallbacks[ handle ];
+                                                                       }
+                                                               }
+
+                                                               // If it's an abort
+                                                               if ( isAbort ) {
+                                                                       // Abort it manually if needed
+                                                                       if ( xhr.readyState !== 4 ) {
+                                                                               xhr.abort();
+                                                                       }
+                                                               } else {
+                                                                       status = xhr.status;
+                                                                       responseHeaders = xhr.getAllResponseHeaders();
+                                                                       responses = {};
+                                                                       xml = xhr.responseXML;
+
+                                                                       // Construct response list
+                                                                       if ( xml && xml.documentElement /* #4958 */ ) {
+                                                                               responses.xml = xml;
+                                                                       }
+                                                                       responses.text = xhr.responseText;
+
+                                                                       // Firefox throws an exception when accessing
+                                                                       // statusText for faulty cross-domain requests
+                                                                       try {
+                                                                               statusText = xhr.statusText;
+                                                                       } catch( e ) {
+                                                                               // We normalize with Webkit giving an empty statusText
+                                                                               statusText = "";
+                                                                       }
+
+                                                                       // Filter status for non standard behaviors
+
+                                                                       // If the request is local and we have data: assume a success
+                                                                       // (success with no data won't get notified, that's the best we
+                                                                       // can do given current implementations)
+                                                                       if ( !status && s.isLocal && !s.crossDomain ) {
+                                                                               status = responses.text ? 200 : 404;
+                                                                       // IE - #1450: sometimes returns 1223 when it should be 204
+                                                                       } else if ( status === 1223 ) {
+                                                                               status = 204;
+                                                                       }
+                                                               }
+                                                       }
+                                               } catch( firefoxAccessException ) {
+                                                       if ( !isAbort ) {
+                                                               complete( -1, firefoxAccessException );
+                                                       }
+                                               }
+
+                                               // Call complete if needed
+                                               if ( responses ) {
+                                                       complete( status, statusText, responses, responseHeaders );
+                                               }
+                                       };
+
+                                       // if we're in sync mode or it's in cache
+                                       // and has been retrieved directly (IE6 & IE7)
+                                       // we need to manually fire the callback
+                                       if ( !s.async || xhr.readyState === 4 ) {
+                                               callback();
+                                       } else {
+                                               handle = ++xhrId;
+                                               if ( xhrOnUnloadAbort ) {
+                                                       // Create the active xhrs callbacks list if needed
+                                                       // and attach the unload handler
+                                                       if ( !xhrCallbacks ) {
+                                                               xhrCallbacks = {};
+                                                               jQuery( window ).unload( xhrOnUnloadAbort );
+                                                       }
+                                                       // Add to list of active xhrs callbacks
+                                                       xhrCallbacks[ handle ] = callback;
+                                               }
+                                               xhr.onreadystatechange = callback;
+                                       }
+                               },
+
+                               abort: function() {
+                                       if ( callback ) {
+                                               callback(0,1);
+                                       }
+                               }
+                       };
+               }
+       });
+}
+
+
+
+
+var elemdisplay = {},
+       iframe, iframeDoc,
+       rfxtypes = /^(?:toggle|show|hide)$/,
+       rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
+       timerId,
+       fxAttrs = [
+               // height animations
+               [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+               // width animations
+               [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+               // opacity animations
+               [ "opacity" ]
+       ],
+       fxNow,
+       requestAnimationFrame = window.webkitRequestAnimationFrame ||
+           window.mozRequestAnimationFrame ||
+           window.oRequestAnimationFrame;
+
+jQuery.fn.extend({
+       show: function( speed, easing, callback ) {
+               var elem, display;
+
+               if ( speed || speed === 0 ) {
+                       return this.animate( genFx("show", 3), speed, easing, callback);
+
+               } else {
+                       for ( var i = 0, j = this.length; i < j; i++ ) {
+                               elem = this[i];
+
+                               if ( elem.style ) {
+                                       display = elem.style.display;
+
+                                       // Reset the inline display of this element to learn if it is
+                                       // being hidden by cascaded rules or not
+                                       if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
+                                               display = elem.style.display = "";
+                                       }
+
+                                       // Set elements which have been overridden with display: none
+                                       // in a stylesheet to whatever the default browser style is
+                                       // for such an element
+                                       if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
+                                               jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
+                                       }
+                               }
+                       }
+
+                       // Set the display of most of the elements in a second loop
+                       // to avoid the constant reflow
+                       for ( i = 0; i < j; i++ ) {
+                               elem = this[i];
+
+                               if ( elem.style ) {
+                                       display = elem.style.display;
+
+                                       if ( display === "" || display === "none" ) {
+                                               elem.style.display = jQuery._data(elem, "olddisplay") || "";
+                                       }
+                               }
+                       }
+
+                       return this;
+               }
+       },
+
+       hide: function( speed, easing, callback ) {
+               if ( speed || speed === 0 ) {
+                       return this.animate( genFx("hide", 3), speed, easing, callback);
+
+               } else {
+                       for ( var i = 0, j = this.length; i < j; i++ ) {
+                               if ( this[i].style ) {
+                                       var display = jQuery.css( this[i], "display" );
+
+                                       if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
+                                               jQuery._data( this[i], "olddisplay", display );
+                                       }
+                               }
+                       }
+
+                       // Set the display of the elements in a second loop
+                       // to avoid the constant reflow
+                       for ( i = 0; i < j; i++ ) {
+                               if ( this[i].style ) {
+                                       this[i].style.display = "none";
+                               }
+                       }
+
+                       return this;
+               }
+       },
+
+       // Save the old toggle function
+       _toggle: jQuery.fn.toggle,
+
+       toggle: function( fn, fn2, callback ) {
+               var bool = typeof fn === "boolean";
+
+               if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+                       this._toggle.apply( this, arguments );
+
+               } else if ( fn == null || bool ) {
+                       this.each(function() {
+                               var state = bool ? fn : jQuery(this).is(":hidden");
+                               jQuery(this)[ state ? "show" : "hide" ]();
+                       });
+
+               } else {
+                       this.animate(genFx("toggle", 3), fn, fn2, callback);
+               }
+
+               return this;
+       },
+
+       fadeTo: function( speed, to, easing, callback ) {
+               return this.filter(":hidden").css("opacity", 0).show().end()
+                                       .animate({opacity: to}, speed, easing, callback);
+       },
+
+       animate: function( prop, speed, easing, callback ) {
+               var optall = jQuery.speed(speed, easing, callback);
+
+               if ( jQuery.isEmptyObject( prop ) ) {
+                       return this.each( optall.complete, [ false ] );
+               }
+
+               return this[ optall.queue === false ? "each" : "queue" ](function() {
+                       // XXX 'this' does not always have a nodeName when running the
+                       // test suite
+
+                       if ( optall.queue === false ) {
+                               jQuery._mark( this );
+                       }
+
+                       var opt = jQuery.extend({}, optall),
+                               isElement = this.nodeType === 1,
+                               hidden = isElement && jQuery(this).is(":hidden"),
+                               name, val, p,
+                               display, e,
+                               parts, start, end, unit;
+
+                       // will store per property easing and be used to determine when an animation is complete
+                       opt.animatedProperties = {};
+
+                       for ( p in prop ) {
+
+                               // property name normalization
+                               name = jQuery.camelCase( p );
+                               if ( p !== name ) {
+                                       prop[ name ] = prop[ p ];
+                                       delete prop[ p ];
+                               }
+
+                               val = prop[name];
+
+                               if ( val === "hide" && hidden || val === "show" && !hidden ) {
+                                       return opt.complete.call(this);
+                               }
+
+                               if ( isElement && ( name === "height" || name === "width" ) ) {
+                                       // Make sure that nothing sneaks out
+                                       // Record all 3 overflow attributes because IE does not
+                                       // change the overflow attribute when overflowX and
+                                       // overflowY are set to the same value
+                                       opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
+
+                                       // Set display property to inline-block for height/width
+                                       // animations on inline elements that are having width/height
+                                       // animated
+                                       if ( jQuery.css( this, "display" ) === "inline" &&
+                                                       jQuery.css( this, "float" ) === "none" ) {
+                                               if ( !jQuery.support.inlineBlockNeedsLayout ) {
+                                                       this.style.display = "inline-block";
+
+                                               } else {
+                                                       display = defaultDisplay(this.nodeName);
+
+                                                       // inline-level elements accept inline-block;
+                                                       // block-level elements need to be inline with layout
+                                                       if ( display === "inline" ) {
+                                                               this.style.display = "inline-block";
+
+                                                       } else {
+                                                               this.style.display = "inline";
+                                                               this.style.zoom = 1;
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
+                               opt.animatedProperties[name] = jQuery.isArray( val ) ?
+                                       val[1]:
+                                       opt.specialEasing && opt.specialEasing[name] || opt.easing || 'swing';
+                       }
+
+                       if ( opt.overflow != null ) {
+                               this.style.overflow = "hidden";
+                       }
+
+                       for ( p in prop ) {
+                               e = new jQuery.fx( this, opt, p );
+
+                               val = prop[p];
+
+                               if ( rfxtypes.test(val) ) {
+                                       e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
+
+                               } else {
+                                       parts = rfxnum.exec(val);
+                                       start = e.cur();
+
+                                       if ( parts ) {
+                                               end = parseFloat( parts[2] );
+                                               unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" );
+
+                                               // We need to compute starting value
+                                               if ( unit !== "px" ) {
+                                                       jQuery.style( this, p, (end || 1) + unit);
+                                                       start = ((end || 1) / e.cur()) * start;
+                                                       jQuery.style( this, p, start + unit);
+                                               }
+
+                                               // If a +=/-= token was provided, we're doing a relative animation
+                                               if ( parts[1] ) {
+                                                       end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
+                                               }
+
+                                               e.custom( start, end, unit );
+
+                                       } else {
+                                               e.custom( start, val, "" );
+                                       }
+                               }
+                       }
+
+                       // For JS strict compliance
+                       return true;
+               });
+       },
+
+       stop: function( clearQueue, gotoEnd ) {
+               if ( clearQueue ) {
+                       this.queue([]);
+               }
+
+               this.each(function() {
+                       var timers = jQuery.timers,
+                               i = timers.length;
+                       // clear marker counters if we know they won't be
+                       if ( !gotoEnd ) {
+                               jQuery._unmark( true, this );
+                       }
+                       // go in reverse order so anything added to the queue during the loop is ignored
+                       while ( i-- ) {
+                               if ( timers[i].elem === this ) {
+                                       if (gotoEnd) {
+                                               // force the next step to be the last
+                                               timers[i](true);
+                                       }
+
+                                       timers.splice(i, 1);
+                               }
+                       }
+               });
+
+               // start the next in the queue if the last step wasn't forced
+               if ( !gotoEnd ) {
+                       this.dequeue();
+               }
+
+               return this;
+       }
+
+});
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+       setTimeout( clearFxNow, 0 );
+       return ( fxNow = jQuery.now() );
+}
+
+function clearFxNow() {
+       fxNow = undefined;
+}
+
+// Generate parameters to create a standard animation
+function genFx( type, num ) {
+       var obj = {};
+
+       jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+               obj[ this ] = type;
+       });
+
+       return obj;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+       slideDown: genFx("show", 1),
+       slideUp: genFx("hide", 1),
+       slideToggle: genFx("toggle", 1),
+       fadeIn: { opacity: "show" },
+       fadeOut: { opacity: "hide" },
+       fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+       jQuery.fn[ name ] = function( speed, easing, callback ) {
+               return this.animate( props, speed, easing, callback );
+       };
+});
+
+jQuery.extend({
+       speed: function( speed, easing, fn ) {
+               var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
+                       complete: fn || !fn && easing ||
+                               jQuery.isFunction( speed ) && speed,
+                       duration: speed,
+                       easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+               };
+
+               opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+                       opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
+
+               // Queueing
+               opt.old = opt.complete;
+               opt.complete = function( noUnmark ) {
+                       if ( opt.queue !== false ) {
+                               jQuery.dequeue( this );
+                       } else if ( noUnmark !== false ) {
+                               jQuery._unmark( this );
+                       }
+
+                       if ( jQuery.isFunction( opt.old ) ) {
+                               opt.old.call( this );
+                       }
+               };
+
+               return opt;
+       },
+
+       easing: {
+               linear: function( p, n, firstNum, diff ) {
+                       return firstNum + diff * p;
+               },
+               swing: function( p, n, firstNum, diff ) {
+                       return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+               }
+       },
+
+       timers: [],
+
+       fx: function( elem, options, prop ) {
+               this.options = options;
+               this.elem = elem;
+               this.prop = prop;
+
+               options.orig = options.orig || {};
+       }
+
+});
+
+jQuery.fx.prototype = {
+       // Simple function for setting a style value
+       update: function() {
+               if ( this.options.step ) {
+                       this.options.step.call( this.elem, this.now, this );
+               }
+
+               (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+       },
+
+       // Get the current size
+       cur: function() {
+               if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+                       return this.elem[ this.prop ];
+               }
+
+               var parsed,
+                       r = jQuery.css( this.elem, this.prop );
+               // Empty strings, null, undefined and "auto" are converted to 0,
+               // complex values such as "rotate(1rad)" are returned as is,
+               // simple values such as "10px" are parsed to Float.
+               return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
+       },
+
+       // Start an animation from one number to another
+       custom: function( from, to, unit ) {
+               var self = this,
+                       fx = jQuery.fx,
+                       raf;
+
+               this.startTime = fxNow || createFxNow();
+               this.start = from;
+               this.end = to;
+               this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
+               this.now = this.start;
+               this.pos = this.state = 0;
+
+               function t( gotoEnd ) {
+                       return self.step(gotoEnd);
+               }
+
+               t.elem = this.elem;
+
+               if ( t() && jQuery.timers.push(t) && !timerId ) {
+                       // Use requestAnimationFrame instead of setInterval if available
+                       if ( requestAnimationFrame ) {
+                               timerId = 1;
+                               raf = function() {
+                                       // When timerId gets set to null at any point, this stops
+                                       if ( timerId ) {
+                                               requestAnimationFrame( raf );
+                                               fx.tick();
+                                       }
+                               };
+                               requestAnimationFrame( raf );
+                       } else {
+                               timerId = setInterval( fx.tick, fx.interval );
+                       }
+               }
+       },
+
+       // Simple 'show' function
+       show: function() {
+               // Remember where we started, so that we can go back to it later
+               this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+               this.options.show = true;
+
+               // Begin the animation
+               // Make sure that we start at a small width/height to avoid any
+               // flash of content
+               this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+               // Start by showing the element
+               jQuery( this.elem ).show();
+       },
+
+       // Simple 'hide' function
+       hide: function() {
+               // Remember where we started, so that we can go back to it later
+               this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+               this.options.hide = true;
+
+               // Begin the animation
+               this.custom(this.cur(), 0);
+       },
+
+       // Each step of an animation
+       step: function( gotoEnd ) {
+               var t = fxNow || createFxNow(),
+                       done = true,
+                       elem = this.elem,
+                       options = this.options,
+                       i, n;
+
+               if ( gotoEnd || t >= options.duration + this.startTime ) {
+                       this.now = this.end;
+                       this.pos = this.state = 1;
+                       this.update();
+
+                       options.animatedProperties[ this.prop ] = true;
+
+                       for ( i in options.animatedProperties ) {
+                               if ( options.animatedProperties[i] !== true ) {
+                                       done = false;
+                               }
+                       }
+
+                       if ( done ) {
+                               // Reset the overflow
+                               if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
+
+                                       jQuery.each( [ "", "X", "Y" ], function (index, value) {
+                                               elem.style[ "overflow" + value ] = options.overflow[index];
+                                       });
+                               }
+
+                               // Hide the element if the "hide" operation was done
+                               if ( options.hide ) {
+                                       jQuery(elem).hide();
+                               }
+
+                               // Reset the properties, if the item has been hidden or shown
+                               if ( options.hide || options.show ) {
+                                       for ( var p in options.animatedProperties ) {
+                                               jQuery.style( elem, p, options.orig[p] );
+                                       }
+                               }
+
+                               // Execute the complete function
+                               options.complete.call( elem );
+                       }
+
+                       return false;
+
+               } else {
+                       // classical easing cannot be used with an Infinity duration
+                       if ( options.duration == Infinity ) {
+                               this.now = t;
+                       } else {
+                               n = t - this.startTime;
+
+                               this.state = n / options.duration;
+                               // Perform the easing function, defaults to swing
+                               this.pos = jQuery.easing[options.animatedProperties[this.prop]](this.state, n, 0, 1, options.duration);
+                               this.now = this.start + ((this.end - this.start) * this.pos);
+                       }
+                       // Perform the next step of the animation
+                       this.update();
+               }
+
+               return true;
+       }
+};
+
+jQuery.extend( jQuery.fx, {
+       tick: function() {
+               var timers = jQuery.timers,
+                       i = timers.length;
+               while ( i-- ) {
+                       if ( !timers[i]() ) {
+                               timers.splice(i, 1);
+                       }
+               }
+
+               if ( !timers.length ) {
+                       jQuery.fx.stop();
+               }
+       },
+
+       interval: 13,
+
+       stop: function() {
+               clearInterval( timerId );
+               timerId = null;
+       },
+
+       speeds: {
+               slow: 600,
+               fast: 200,
+               // Default speed
+               _default: 400
+       },
+
+       step: {
+               opacity: function( fx ) {
+                       jQuery.style( fx.elem, "opacity", fx.now );
+               },
+
+               _default: function( fx ) {
+                       if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+                               fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+                       } else {
+                               fx.elem[ fx.prop ] = fx.now;
+                       }
+               }
+       }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+       jQuery.expr.filters.animated = function( elem ) {
+               return jQuery.grep(jQuery.timers, function( fn ) {
+                       return elem === fn.elem;
+               }).length;
+       };
+}
+
+// Try to restore the default display value of an element
+function defaultDisplay( nodeName ) {
+
+       if ( !elemdisplay[ nodeName ] ) {
+
+               var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
+                       display = elem.css( "display" );
+
+               elem.remove();
+
+               // If the simple way fails,
+               // get element's real default display by attaching it to a temp iframe
+               if ( display === "none" || display === "" ) {
+                       // No iframe to use yet, so create it
+                       if ( !iframe ) {
+                               iframe = document.createElement( "iframe" );
+                               iframe.frameBorder = iframe.width = iframe.height = 0;
+                       }
+
+                       document.body.appendChild( iframe );
+
+                       // Create a cacheable copy of the iframe document on first call.
+                       // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
+                       // document to it, Webkit & Firefox won't allow reusing the iframe document
+                       if ( !iframeDoc || !iframe.createElement ) {
+                               iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
+                               iframeDoc.write( "<!doctype><html><body></body></html>" );
+                       }
+
+                       elem = iframeDoc.createElement( nodeName );
+
+                       iframeDoc.body.appendChild( elem );
+
+                       display = jQuery.css( elem, "display" );
+
+                       document.body.removeChild( iframe );
+               }
+
+               // Store the correct default display
+               elemdisplay[ nodeName ] = display;
+       }
+
+       return elemdisplay[ nodeName ];
+}
+
+
+
+
+var rtable = /^t(?:able|d|h)$/i,
+       rroot = /^(?:body|html)$/i;
+
+if ( "getBoundingClientRect" in document.documentElement ) {
+       jQuery.fn.offset = function( options ) {
+               var elem = this[0], box;
+
+               if ( options ) {
+                       return this.each(function( i ) {
+                               jQuery.offset.setOffset( this, options, i );
+                       });
+               }
+
+               if ( !elem || !elem.ownerDocument ) {
+                       return null;
+               }
+
+               if ( elem === elem.ownerDocument.body ) {
+                       return jQuery.offset.bodyOffset( elem );
+               }
+
+               try {
+                       box = elem.getBoundingClientRect();
+               } catch(e) {}
+
+               var doc = elem.ownerDocument,
+                       docElem = doc.documentElement;
+
+               // Make sure we're not dealing with a disconnected DOM node
+               if ( !box || !jQuery.contains( docElem, elem ) ) {
+                       return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
+               }
+
+               var body = doc.body,
+                       win = getWindow(doc),
+                       clientTop  = docElem.clientTop  || body.clientTop  || 0,
+                       clientLeft = docElem.clientLeft || body.clientLeft || 0,
+                       scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
+                       scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
+                       top  = box.top  + scrollTop  - clientTop,
+                       left = box.left + scrollLeft - clientLeft;
+
+               return { top: top, left: left };
+       };
+
+} else {
+       jQuery.fn.offset = function( options ) {
+               var elem = this[0];
+
+               if ( options ) {
+                       return this.each(function( i ) {
+                               jQuery.offset.setOffset( this, options, i );
+                       });
+               }
+
+               if ( !elem || !elem.ownerDocument ) {
+                       return null;
+               }
+
+               if ( elem === elem.ownerDocument.body ) {
+                       return jQuery.offset.bodyOffset( elem );
+               }
+
+               jQuery.offset.initialize();
+
+               var computedStyle,
+                       offsetParent = elem.offsetParent,
+                       prevOffsetParent = elem,
+                       doc = elem.ownerDocument,
+                       docElem = doc.documentElement,
+                       body = doc.body,
+                       defaultView = doc.defaultView,
+                       prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+                       top = elem.offsetTop,
+                       left = elem.offsetLeft;
+
+               while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+                       if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+                               break;
+                       }
+
+                       computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+                       top  -= elem.scrollTop;
+                       left -= elem.scrollLeft;
+
+                       if ( elem === offsetParent ) {
+                               top  += elem.offsetTop;
+                               left += elem.offsetLeft;
+
+                               if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
+                                       top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
+                                       left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+                               }
+
+                               prevOffsetParent = offsetParent;
+                               offsetParent = elem.offsetParent;
+                       }
+
+                       if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+                               top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
+                               left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+                       }
+
+                       prevComputedStyle = computedStyle;
+               }
+
+               if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+                       top  += body.offsetTop;
+                       left += body.offsetLeft;
+               }
+
+               if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+                       top  += Math.max( docElem.scrollTop, body.scrollTop );
+                       left += Math.max( docElem.scrollLeft, body.scrollLeft );
+               }
+
+               return { top: top, left: left };
+       };
+}
+
+jQuery.offset = {
+       initialize: function() {
+               var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
+                       html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+               jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+               container.innerHTML = html;
+               body.insertBefore( container, body.firstChild );
+               innerDiv = container.firstChild;
+               checkDiv = innerDiv.firstChild;
+               td = innerDiv.nextSibling.firstChild.firstChild;
+
+               this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+               this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+               checkDiv.style.position = "fixed";
+               checkDiv.style.top = "20px";
+
+               // safari subtracts parent border width here which is 5px
+               this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+               checkDiv.style.position = checkDiv.style.top = "";
+
+               innerDiv.style.overflow = "hidden";
+               innerDiv.style.position = "relative";
+
+               this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+               this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+               body.removeChild( container );
+               jQuery.offset.initialize = jQuery.noop;
+       },
+
+       bodyOffset: function( body ) {
+               var top = body.offsetTop,
+                       left = body.offsetLeft;
+
+               jQuery.offset.initialize();
+
+               if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+                       top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
+                       left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
+               }
+
+               return { top: top, left: left };
+       },
+
+       setOffset: function( elem, options, i ) {
+               var position = jQuery.css( elem, "position" );
+
+               // set position first, in-case top/left are set even on static elem
+               if ( position === "static" ) {
+                       elem.style.position = "relative";
+               }
+
+               var curElem = jQuery( elem ),
+                       curOffset = curElem.offset(),
+                       curCSSTop = jQuery.css( elem, "top" ),
+                       curCSSLeft = jQuery.css( elem, "left" ),
+                       calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+                       props = {}, curPosition = {}, curTop, curLeft;
+
+               // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+               if ( calculatePosition ) {
+                       curPosition = curElem.position();
+                       curTop = curPosition.top;
+                       curLeft = curPosition.left;
+               } else {
+                       curTop = parseFloat( curCSSTop ) || 0;
+                       curLeft = parseFloat( curCSSLeft ) || 0;
+               }
+
+               if ( jQuery.isFunction( options ) ) {
+                       options = options.call( elem, i, curOffset );
+               }
+
+               if (options.top != null) {
+                       props.top = (options.top - curOffset.top) + curTop;
+               }
+               if (options.left != null) {
+                       props.left = (options.left - curOffset.left) + curLeft;
+               }
+
+               if ( "using" in options ) {
+                       options.using.call( elem, props );
+               } else {
+                       curElem.css( props );
+               }
+       }
+};
+
+
+jQuery.fn.extend({
+       position: function() {
+               if ( !this[0] ) {
+                       return null;
+               }
+
+               var elem = this[0],
+
+               // Get *real* offsetParent
+               offsetParent = this.offsetParent(),
+
+               // Get correct offsets
+               offset       = this.offset(),
+               parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+               // Subtract element margins
+               // note: when an element has margin: auto the offsetLeft and marginLeft
+               // are the same in Safari causing offset.left to incorrectly be 0
+               offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
+               offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
+
+               // Add offsetParent borders
+               parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
+               parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
+
+               // Subtract the two offsets
+               return {
+                       top:  offset.top  - parentOffset.top,
+                       left: offset.left - parentOffset.left
+               };
+       },
+
+       offsetParent: function() {
+               return this.map(function() {
+                       var offsetParent = this.offsetParent || document.body;
+                       while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+                               offsetParent = offsetParent.offsetParent;
+                       }
+                       return offsetParent;
+               });
+       }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+       var method = "scroll" + name;
+
+       jQuery.fn[ method ] = function( val ) {
+               var elem, win;
+
+               if ( val === undefined ) {
+                       elem = this[ 0 ];
+
+                       if ( !elem ) {
+                               return null;
+                       }
+
+                       win = getWindow( elem );
+
+                       // Return the scroll offset
+                       return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+                               jQuery.support.boxModel && win.document.documentElement[ method ] ||
+                                       win.document.body[ method ] :
+                               elem[ method ];
+               }
+
+               // Set the scroll offset
+               return this.each(function() {
+                       win = getWindow( this );
+
+                       if ( win ) {
+                               win.scrollTo(
+                                       !i ? val : jQuery( win ).scrollLeft(),
+                                        i ? val : jQuery( win ).scrollTop()
+                               );
+
+                       } else {
+                               this[ method ] = val;
+                       }
+               });
+       };
+});
+
+function getWindow( elem ) {
+       return jQuery.isWindow( elem ) ?
+               elem :
+               elem.nodeType === 9 ?
+                       elem.defaultView || elem.parentWindow :
+                       false;
+}
+
+
+
+
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+       var type = name.toLowerCase();
+
+       // innerHeight and innerWidth
+       jQuery.fn["inner" + name] = function() {
+               return this[0] ?
+                       parseFloat( jQuery.css( this[0], type, "padding" ) ) :
+                       null;
+       };
+
+       // outerHeight and outerWidth
+       jQuery.fn["outer" + name] = function( margin ) {
+               return this[0] ?
+                       parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
+                       null;
+       };
+
+       jQuery.fn[ type ] = function( size ) {
+               // Get window width or height
+               var elem = this[0];
+               if ( !elem ) {
+                       return size == null ? null : this;
+               }
+
+               if ( jQuery.isFunction( size ) ) {
+                       return this.each(function( i ) {
+                               var self = jQuery( this );
+                               self[ type ]( size.call( this, i, self[ type ]() ) );
+                       });
+               }
+
+               if ( jQuery.isWindow( elem ) ) {
+                       // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+                       // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
+                       var docElemProp = elem.document.documentElement[ "client" + name ];
+                       return elem.document.compatMode === "CSS1Compat" && docElemProp ||
+                               elem.document.body[ "client" + name ] || docElemProp;
+
+               // Get document width or height
+               } else if ( elem.nodeType === 9 ) {
+                       // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+                       return Math.max(
+                               elem.documentElement["client" + name],
+                               elem.body["scroll" + name], elem.documentElement["scroll" + name],
+                               elem.body["offset" + name], elem.documentElement["offset" + name]
+                       );
+
+               // Get or set width or height on the element
+               } else if ( size === undefined ) {
+                       var orig = jQuery.css( elem, type ),
+                               ret = parseFloat( orig );
+
+                       return jQuery.isNaN( ret ) ? orig : ret;
+
+               // Set the width or height on the element (default to pixels if value is unitless)
+               } else {
+                       return this.css( type, typeof size === "string" ? size : size + "px" );
+               }
+       };
+
+});
+
+
+window.jQuery = window.$ = jQuery;
+})(window);
+/*!
+ * jQuery UI 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * licensed under MIT 
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function( $, undefined ) {
+
+// prevent duplicate loading
+// this is only a problem because we proxy existing functions
+// and we don't want to double proxy them
+$.ui = $.ui || {};
+if ( $.ui.version ) {
+       return;
+}
+
+$.extend( $.ui, {
+       version: "1.8.12",
+
+       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
+       }
+});
+
+// plugins
+$.fn.extend({
+       _focus: $.fn.focus,
+       focus: function( delay, fn ) {
+               return typeof delay === "number" ?
+                       this.each(function() {
+                               var elem = this;
+                               setTimeout(function() {
+                                       $( elem ).focus();
+                                       if ( fn ) {
+                                               fn.call( elem );
+                                       }
+                               }, delay );
+                       }) :
+                       this._focus.apply( this, arguments );
+       },
+
+       scrollParent: function() {
+               var scrollParent;
+               if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
+                       scrollParent = this.parents().filter(function() {
+                               return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+                       }).eq(0);
+               } else {
+                       scrollParent = this.parents().filter(function() {
+                               return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+                       }).eq(0);
+               }
+
+               return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
+       },
+
+       zIndex: function( zIndex ) {
+               if ( zIndex !== undefined ) {
+                       return this.css( "zIndex", zIndex );
+               }
+
+               if ( this.length ) {
+                       var elem = $( this[ 0 ] ), position, value;
+                       while ( elem.length && elem[ 0 ] !== document ) {
+                               // Ignore z-index if position is set to a value where z-index is ignored by the browser
+                               // This makes behavior of this function consistent across browsers
+                               // WebKit always returns auto if the element is positioned
+                               position = elem.css( "position" );
+                               if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+                                       // IE returns 0 when zIndex is not specified
+                                       // other browsers return a string
+                                       // we ignore the case of nested elements with an explicit value of 0
+                                       // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+                                       value = parseInt( elem.css( "zIndex" ), 10 );
+                                       if ( !isNaN( value ) && value !== 0 ) {
+                                               return value;
+                                       }
+                               }
+                               elem = elem.parent();
+                       }
+               }
+
+               return 0;
+       },
+
+       disableSelection: function() {
+               return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
+                       ".ui-disableSelection", function( event ) {
+                               event.preventDefault();
+                       });
+       },
+
+       enableSelection: function() {
+               return this.unbind( ".ui-disableSelection" );
+       }
+});
+
+$.each( [ "Width", "Height" ], function( i, name ) {
+       var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+               type = name.toLowerCase(),
+               orig = {
+                       innerWidth: $.fn.innerWidth,
+                       innerHeight: $.fn.innerHeight,
+                       outerWidth: $.fn.outerWidth,
+                       outerHeight: $.fn.outerHeight
+               };
+
+       function reduce( elem, size, border, margin ) {
+               $.each( side, function() {
+                       size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
+                       if ( border ) {
+                               size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
+                       }
+                       if ( margin ) {
+                               size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
+                       }
+               });
+               return size;
+       }
+
+       $.fn[ "inner" + name ] = function( size ) {
+               if ( size === undefined ) {
+                       return orig[ "inner" + name ].call( this );
+               }
+
+               return this.each(function() {
+                       $( this ).css( type, reduce( this, size ) + "px" );
+               });
+       };
+
+       $.fn[ "outer" + name] = function( size, margin ) {
+               if ( typeof size !== "number" ) {
+                       return orig[ "outer" + name ].call( this, size );
+               }
+
+               return this.each(function() {
+                       $( this).css( type, reduce( this, size, true, margin ) + "px" );
+               });
+       };
+});
+
+// selectors
+function visible( element ) {
+       return !$( element ).parents().andSelf().filter(function() {
+               return $.curCSS( this, "visibility" ) === "hidden" ||
+                       $.expr.filters.hidden( this );
+       }).length;
+}
+
+$.extend( $.expr[ ":" ], {
+       data: function( elem, i, match ) {
+               return !!$.data( elem, match[ 3 ] );
+       },
+
+       focusable: function( element ) {
+               var nodeName = element.nodeName.toLowerCase(),
+                       tabIndex = $.attr( element, "tabindex" );
+               if ( "area" === nodeName ) {
+                       var map = element.parentNode,
+                               mapName = map.name,
+                               img;
+                       if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+                               return false;
+                       }
+                       img = $( "img[usemap=#" + mapName + "]" )[0];
+                       return !!img && visible( img );
+               }
+               return ( /input|select|textarea|button|object/.test( nodeName )
+                       ? !element.disabled
+                       : "a" == nodeName
+                               ? element.href || !isNaN( tabIndex )
+                               : !isNaN( tabIndex ))
+                       // the element and all of its ancestors must be visible
+                       && visible( element );
+       },
+
+       tabbable: function( element ) {
+               var tabIndex = $.attr( element, "tabindex" );
+               return ( isNaN( tabIndex ) || tabIndex >= 0 ) && $( element ).is( ":focusable" );
+       }
+});
+
+// support
+$(function() {
+       var body = document.body,
+               div = body.appendChild( div = document.createElement( "div" ) );
+
+       $.extend( div.style, {
+               minHeight: "100px",
+               height: "auto",
+               padding: 0,
+               borderWidth: 0
+       });
+
+       $.support.minHeight = div.offsetHeight === 100;
+       $.support.selectstart = "onselectstart" in div;
+
+       // set display to none to avoid a layout bug in IE
+       // http://dev.jquery.com/ticket/4014
+       body.removeChild( div ).style.display = "none";
+});
+
+
+
+
+
+// deprecated
+$.extend( $.ui, {
+       // $.ui.plugin is deprecated.  Use the proxy pattern instead.
+       plugin: {
+               add: function( module, option, set ) {
+                       var proto = $.ui[ module ].prototype;
+                       for ( var i in set ) {
+                               proto.plugins[ i ] = proto.plugins[ i ] || [];
+                               proto.plugins[ i ].push( [ option, set[ i ] ] );
+                       }
+               },
+               call: function( instance, name, args ) {
+                       var set = instance.plugins[ name ];
+                       if ( !set || !instance.element[ 0 ].parentNode ) {
+                               return;
+                       }
+       
+                       for ( var i = 0; i < set.length; i++ ) {
+                               if ( instance.options[ set[ i ][ 0 ] ] ) {
+                                       set[ i ][ 1 ].apply( instance.element, args );
+                               }
+                       }
+               }
+       },
+       
+       // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
+       contains: function( a, b ) {
+               return document.compareDocumentPosition ?
+                       a.compareDocumentPosition( b ) & 16 :
+                       a !== b && a.contains( b );
+       },
+       
+       // only used by resizable
+       hasScroll: function( el, a ) {
+       
+               //If overflow is hidden, the element might have extra content, but the user wants to hide it
+               if ( $( el ).css( "overflow" ) === "hidden") {
+                       return false;
+               }
+       
+               var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+                       has = false;
+       
+               if ( el[ scroll ] > 0 ) {
+                       return true;
+               }
+       
+               // TODO: determine which cases actually cause this to happen
+               // if the element doesn't have the scroll set, see if it's possible to
+               // set the scroll
+               el[ scroll ] = 1;
+               has = ( el[ scroll ] > 0 );
+               el[ scroll ] = 0;
+               return has;
+       },
+       
+       // these are odd functions, fix the API or move into individual plugins
+       isOverAxis: function( x, reference, size ) {
+               //Determines when x coordinate is over "b" element axis
+               return ( x > reference ) && ( x < ( reference + size ) );
+       },
+       isOver: function( y, x, top, left, height, width ) {
+               //Determines when x, y coordinates is over "b" element
+               return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
+       }
+});
+
+})( jQuery );
+/*!
+ * jQuery UI Widget 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function( $, undefined ) {
+
+// jQuery 1.4+
+if ( $.cleanData ) {
+       var _cleanData = $.cleanData;
+       $.cleanData = function( elems ) {
+               for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+                       $( elem ).triggerHandler( "remove" );
+               }
+               _cleanData( elems );
+       };
+} else {
+       var _remove = $.fn.remove;
+       $.fn.remove = function( selector, keepData ) {
+               return this.each(function() {
+                       if ( !keepData ) {
+                               if ( !selector || $.filter( selector, [ this ] ).length ) {
+                                       $( "*", this ).add( [ this ] ).each(function() {
+                                               $( this ).triggerHandler( "remove" );
+                                       });
+                               }
+                       }
+                       return _remove.call( $(this), selector, keepData );
+               });
+       };
+}
+
+$.widget = function( name, base, prototype ) {
+       var namespace = name.split( "." )[ 0 ],
+               fullName;
+       name = name.split( "." )[ 1 ];
+       fullName = namespace + "-" + name;
+
+       if ( !prototype ) {
+               prototype = base;
+               base = $.Widget;
+       }
+
+       // create selector for plugin
+       $.expr[ ":" ][ fullName ] = function( elem ) {
+               return !!$.data( elem, name );
+       };
+
+       $[ namespace ] = $[ namespace ] || {};
+       $[ namespace ][ name ] = function( options, element ) {
+               // allow instantiation without initializing for simple inheritance
+               if ( arguments.length ) {
+                       this._createWidget( options, element );
+               }
+       };
+
+       var 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
+//     $.each( basePrototype, function( key, val ) {
+//             if ( $.isPlainObject(val) ) {
+//                     basePrototype[ key ] = $.extend( {}, val );
+//             }
+//     });
+       basePrototype.options = $.extend( true, {}, basePrototype.options );
+       $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
+               namespace: namespace,
+               widgetName: name,
+               widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
+               widgetBaseClass: fullName
+       }, prototype );
+
+       $.widget.bridge( name, $[ namespace ][ name ] );
+};
+
+$.widget.bridge = function( name, object ) {
+       $.fn[ name ] = function( options ) {
+               var isMethodCall = typeof options === "string",
+                       args = Array.prototype.slice.call( arguments, 1 ),
+                       returnValue = this;
+
+               // allow multiple hashes to be passed on init
+               options = !isMethodCall && args.length ?
+                       $.extend.apply( null, [ true, options ].concat(args) ) :
+                       options;
+
+               // prevent calls to internal methods
+               if ( isMethodCall && options.charAt( 0 ) === "_" ) {
+                       return returnValue;
+               }
+
+               if ( isMethodCall ) {
+                       this.each(function() {
+                               var instance = $.data( this, name ),
+                                       methodValue = instance && $.isFunction( instance[options] ) ?
+                                               instance[ options ].apply( instance, args ) :
+                                               instance;
+                               // TODO: add this back in 1.9 and use $.error() (see #5972)
+//                             if ( !instance ) {
+//                                     throw "cannot call methods on " + name + " prior to initialization; " +
+//                                             "attempted to call method '" + options + "'";
+//                             }
+//                             if ( !$.isFunction( instance[options] ) ) {
+//                                     throw "no such method '" + options + "' for " + name + " widget instance";
+//                             }
+//                             var methodValue = instance[ options ].apply( instance, args );
+                               if ( methodValue !== instance && methodValue !== undefined ) {
+                                       returnValue = methodValue;
+                                       return false;
+                               }
+                       });
+               } else {
+                       this.each(function() {
+                               var instance = $.data( this, name );
+                               if ( instance ) {
+                                       instance.option( options || {} )._init();
+                               } else {
+                                       $.data( this, name, new object( options, this ) );
+                               }
+                       });
+               }
+
+               return returnValue;
+       };
+};
+
+$.Widget = function( options, element ) {
+       // allow instantiation without initializing for simple inheritance
+       if ( arguments.length ) {
+               this._createWidget( options, element );
+       }
+};
+
+$.Widget.prototype = {
+       widgetName: "widget",
+       widgetEventPrefix: "",
+       options: {
+               disabled: false
+       },
+       _createWidget: function( options, element ) {
+               // $.widget.bridge stores the plugin instance, but we do it anyway
+               // so that it's stored even before the _create function runs
+               $.data( element, this.widgetName, this );
+               this.element = $( element );
+               this.options = $.extend( true, {},
+                       this.options,
+                       this._getCreateOptions(),
+                       options );
+
+               var self = this;
+               this.element.bind( "remove." + this.widgetName, function() {
+                       self.destroy();
+               });
+
+               this._create();
+               this._trigger( "create" );
+               this._init();
+       },
+       _getCreateOptions: function() {
+               return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
+       },
+       _create: function() {},
+       _init: function() {},
+
+       destroy: function() {
+               this.element
+                       .unbind( "." + this.widgetName )
+                       .removeData( this.widgetName );
+               this.widget()
+                       .unbind( "." + this.widgetName )
+                       .removeAttr( "aria-disabled" )
+                       .removeClass(
+                               this.widgetBaseClass + "-disabled " +
+                               "ui-state-disabled" );
+       },
+
+       widget: function() {
+               return this.element;
+       },
+
+       option: function( key, value ) {
+               var options = key;
+
+               if ( arguments.length === 0 ) {
+                       // don't return a reference to the internal hash
+                       return $.extend( {}, this.options );
+               }
+
+               if  (typeof key === "string" ) {
+                       if ( value === undefined ) {
+                               return this.options[ key ];
+                       }
+                       options = {};
+                       options[ key ] = value;
+               }
+
+               this._setOptions( options );
+
+               return this;
+       },
+       _setOptions: function( options ) {
+               var self = this;
+               $.each( options, function( key, value ) {
+                       self._setOption( key, value );
+               });
+
+               return this;
+       },
+       _setOption: function( key, value ) {
+               this.options[ key ] = value;
+
+               if ( key === "disabled" ) {
+                       this.widget()
+                               [ value ? "addClass" : "removeClass"](
+                                       this.widgetBaseClass + "-disabled" + " " +
+                                       "ui-state-disabled" )
+                               .attr( "aria-disabled", value );
+               }
+
+               return this;
+       },
+
+       enable: function() {
+               return this._setOption( "disabled", false );
+       },
+       disable: function() {
+               return this._setOption( "disabled", true );
+       },
+
+       _trigger: function( type, event, data ) {
+               var callback = this.options[ type ];
+
+               event = $.Event( event );
+               event.type = ( type === this.widgetEventPrefix ?
+                       type :
+                       this.widgetEventPrefix + type ).toLowerCase();
+               data = data || {};
+
+               // 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 ( event.originalEvent ) {
+                       for ( var i = $.event.props.length, prop; i; ) {
+                               prop = $.event.props[ --i ];
+                               event[ prop ] = event.originalEvent[ prop ];
+                       }
+               }
+
+               this.element.trigger( event, data );
+
+               return !( $.isFunction(callback) &&
+                       callback.call( this.element[0], event, data ) === false ||
+                       event.isDefaultPrevented() );
+       }
+};
+
+})( jQuery );
+/*!
+ * jQuery UI Mouse 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ *     jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.mouse", {
+       options: {
+               cancel: ':input,option',
+               distance: 1,
+               delay: 0
+       },
+       _mouseInit: function() {
+               var self = this;
+
+               this.element
+                       .bind('mousedown.'+this.widgetName, function(event) {
+                               return self._mouseDown(event);
+                       })
+                       .bind('click.'+this.widgetName, function(event) {
+                               if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
+                                   $.removeData(event.target, self.widgetName + '.preventClickEvent');
+                                       event.stopImmediatePropagation();
+                                       return false;
+                               }
+                       });
+
+               this.started = false;
+       },
+
+       // TODO: make sure destroying one instance of mouse doesn't mess with
+       // other instances of mouse
+       _mouseDestroy: function() {
+               this.element.unbind('.'+this.widgetName);
+       },
+
+       _mouseDown: function(event) {
+               // don't let more than one widget handle mouseStart
+               // TODO: figure out why we have to use originalEvent
+               event.originalEvent = event.originalEvent || {};
+               if (event.originalEvent.mouseHandled) { return; }
+
+               // we may have missed mouseup (out of window)
+               (this._mouseStarted && this._mouseUp(event));
+
+               this._mouseDownEvent = event;
+
+               var self = this,
+                       btnIsLeft = (event.which == 1),
+                       elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
+               if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+                       return true;
+               }
+
+               this.mouseDelayMet = !this.options.delay;
+               if (!this.mouseDelayMet) {
+                       this._mouseDelayTimer = setTimeout(function() {
+                               self.mouseDelayMet = true;
+                       }, this.options.delay);
+               }
+
+               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+                       this._mouseStarted = (this._mouseStart(event) !== false);
+                       if (!this._mouseStarted) {
+                               event.preventDefault();
+                               return true;
+                       }
+               }
+
+               // Click event may never have fired (Gecko & Opera)
+               if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
+                       $.removeData(event.target, this.widgetName + '.preventClickEvent');
+               }
+
+               // these delegates are required to keep context
+               this._mouseMoveDelegate = function(event) {
+                       return self._mouseMove(event);
+               };
+               this._mouseUpDelegate = function(event) {
+                       return self._mouseUp(event);
+               };
+               $(document)
+                       .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+                       .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+               event.preventDefault();
+               event.originalEvent.mouseHandled = true;
+               return true;
+       },
+
+       _mouseMove: function(event) {
+               // IE mouseup check - mouseup happened when mouse was out of window
+               if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
+                       return this._mouseUp(event);
+               }
+
+               if (this._mouseStarted) {
+                       this._mouseDrag(event);
+                       return event.preventDefault();
+               }
+
+               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+                       this._mouseStarted =
+                               (this._mouseStart(this._mouseDownEvent, event) !== false);
+                       (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+               }
+
+               return !this._mouseStarted;
+       },
+
+       _mouseUp: function(event) {
+               $(document)
+                       .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+                       .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+               if (this._mouseStarted) {
+                       this._mouseStarted = false;
+
+                       if (event.target == this._mouseDownEvent.target) {
+                           $.data(event.target, this.widgetName + '.preventClickEvent', true);
+                       }
+
+                       this._mouseStop(event);
+               }
+
+               return false;
+       },
+
+       _mouseDistanceMet: function(event) {
+               return (Math.max(
+                               Math.abs(this._mouseDownEvent.pageX - event.pageX),
+                               Math.abs(this._mouseDownEvent.pageY - event.pageY)
+                       ) >= this.options.distance
+               );
+       },
+
+       _mouseDelayMet: function(event) {
+               return this.mouseDelayMet;
+       },
+
+       // These are placeholder methods, to be overriden by extending plugin
+       _mouseStart: function(event) {},
+       _mouseDrag: function(event) {},
+       _mouseStop: function(event) {},
+       _mouseCapture: function(event) { return true; }
+});
+
+})(jQuery);
+/*
+ * jQuery UI Draggable 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Draggables
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.mouse.js
+ *     jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.draggable", $.ui.mouse, {
+       widgetEventPrefix: "drag",
+       options: {
+               addClasses: true,
+               appendTo: "parent",
+               axis: false,
+               connectToSortable: false,
+               containment: false,
+               cursor: "auto",
+               cursorAt: false,
+               grid: false,
+               handle: false,
+               helper: "original",
+               iframeFix: false,
+               opacity: false,
+               refreshPositions: false,
+               revert: false,
+               revertDuration: 500,
+               scope: "default",
+               scroll: true,
+               scrollSensitivity: 20,
+               scrollSpeed: 20,
+               snap: false,
+               snapMode: "both",
+               snapTolerance: 20,
+               stack: false,
+               zIndex: false
+       },
+       _create: function() {
+
+               if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
+                       this.element[0].style.position = 'relative';
+
+               (this.options.addClasses && this.element.addClass("ui-draggable"));
+               (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
+
+               this._mouseInit();
+
+       },
+
+       destroy: function() {
+               if(!this.element.data('draggable')) return;
+               this.element
+                       .removeData("draggable")
+                       .unbind(".draggable")
+                       .removeClass("ui-draggable"
+                               + " ui-draggable-dragging"
+                               + " ui-draggable-disabled");
+               this._mouseDestroy();
+
+               return this;
+       },
+
+       _mouseCapture: function(event) {
+
+               var o = this.options;
+
+               // among others, prevent a drag on a resizable-handle
+               if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
+                       return false;
+
+               //Quit if we're not on a valid handle
+               this.handle = this._getHandle(event);
+               if (!this.handle)
+                       return false;
+
+               return true;
+
+       },
+
+       _mouseStart: function(event) {
+
+               var o = this.options;
+
+               //Create and append the visible helper
+               this.helper = this._createHelper(event);
+
+               //Cache the helper size
+               this._cacheHelperProportions();
+
+               //If ddmanager is used for droppables, set the global draggable
+               if($.ui.ddmanager)
+                       $.ui.ddmanager.current = this;
+
+               /*
+                * - Position generation -
+                * This block generates everything position related - it's the core of draggables.
+                */
+
+               //Cache the margins of the original element
+               this._cacheMargins();
+
+               //Store the helper's css position
+               this.cssPosition = this.helper.css("position");
+               this.scrollParent = this.helper.scrollParent();
+
+               //The element's absolute position on the page minus margins
+               this.offset = this.positionAbs = this.element.offset();
+               this.offset = {
+                       top: this.offset.top - this.margins.top,
+                       left: this.offset.left - this.margins.left
+               };
+
+               $.extend(this.offset, {
+                       click: { //Where the click happened, relative to the element
+                               left: event.pageX - this.offset.left,
+                               top: event.pageY - this.offset.top
+                       },
+                       parent: this._getParentOffset(),
+                       relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+               });
+
+               //Generate the original position
+               this.originalPosition = this.position = this._generatePosition(event);
+               this.originalPageX = event.pageX;
+               this.originalPageY = event.pageY;
+
+               //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
+               (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+               //Set a containment if given in the options
+               if(o.containment)
+                       this._setContainment();
+
+               //Trigger event + callbacks
+               if(this._trigger("start", event) === false) {
+                       this._clear();
+                       return false;
+               }
+
+               //Recache the helper size
+               this._cacheHelperProportions();
+
+               //Prepare the droppable offsets
+               if ($.ui.ddmanager && !o.dropBehaviour)
+                       $.ui.ddmanager.prepareOffsets(this, event);
+
+               this.helper.addClass("ui-draggable-dragging");
+               this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+               return true;
+       },
+
+       _mouseDrag: function(event, noPropagation) {
+
+               //Compute the helpers position
+               this.position = this._generatePosition(event);
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               //Call plugins and callbacks and use the resulting position if something is returned
+               if (!noPropagation) {
+                       var ui = this._uiHash();
+                       if(this._trigger('drag', event, ui) === false) {
+                               this._mouseUp({});
+                               return false;
+                       }
+                       this.position = ui.position;
+               }
+
+               if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
+               if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
+               if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+
+               //If we are using droppables, inform the manager about the drop
+               var dropped = false;
+               if ($.ui.ddmanager && !this.options.dropBehaviour)
+                       dropped = $.ui.ddmanager.drop(this, event);
+
+               //if a drop comes from outside (a sortable)
+               if(this.dropped) {
+                       dropped = this.dropped;
+                       this.dropped = false;
+               }
+               
+               //if the original element is removed, don't bother to continue if helper is set to "original"
+               if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
+                       return false;
+
+               if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
+                       var self = this;
+                       $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
+                               if(self._trigger("stop", event) !== false) {
+                                       self._clear();
+                               }
+                       });
+               } else {
+                       if(this._trigger("stop", event) !== false) {
+                               this._clear();
+                       }
+               }
+
+               return false;
+       },
+       
+       cancel: function() {
+               
+               if(this.helper.is(".ui-draggable-dragging")) {
+                       this._mouseUp({});
+               } else {
+                       this._clear();
+               }
+               
+               return this;
+               
+       },
+
+       _getHandle: function(event) {
+
+               var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
+               $(this.options.handle, this.element)
+                       .find("*")
+                       .andSelf()
+                       .each(function() {
+                               if(this == event.target) handle = true;
+                       });
+
+               return handle;
+
+       },
+
+       _createHelper: function(event) {
+
+               var o = this.options;
+               var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
+
+               if(!helper.parents('body').length)
+                       helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
+
+               if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
+                       helper.css("position", "absolute");
+
+               return helper;
+
+       },
+
+       _adjustOffsetFromHelper: function(obj) {
+               if (typeof obj == 'string') {
+                       obj = obj.split(' ');
+               }
+               if ($.isArray(obj)) {
+                       obj = {left: +obj[0], top: +obj[1] || 0};
+               }
+               if ('left' in obj) {
+                       this.offset.click.left = obj.left + this.margins.left;
+               }
+               if ('right' in obj) {
+                       this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+               }
+               if ('top' in obj) {
+                       this.offset.click.top = obj.top + this.margins.top;
+               }
+               if ('bottom' in obj) {
+                       this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+               }
+       },
+
+       _getParentOffset: function() {
+
+               //Get the offsetParent and cache its position
+               this.offsetParent = this.helper.offsetParent();
+               var po = this.offsetParent.offset();
+
+               // This is a special case where we need to modify a offset calculated on start, since the following happened:
+               // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+               // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+               //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+               if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
+                       po.left += this.scrollParent.scrollLeft();
+                       po.top += this.scrollParent.scrollTop();
+               }
+
+               if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
+               || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
+                       po = { top: 0, left: 0 };
+
+               return {
+                       top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+                       left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+               };
+
+       },
+
+       _getRelativeOffset: function() {
+
+               if(this.cssPosition == "relative") {
+                       var p = this.element.position();
+                       return {
+                               top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+                               left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+                       };
+               } else {
+                       return { top: 0, left: 0 };
+               }
+
+       },
+
+       _cacheMargins: function() {
+               this.margins = {
+                       left: (parseInt(this.element.css("marginLeft"),10) || 0),
+                       top: (parseInt(this.element.css("marginTop"),10) || 0),
+                       right: (parseInt(this.element.css("marginRight"),10) || 0),
+                       bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
+               };
+       },
+
+       _cacheHelperProportions: function() {
+               this.helperProportions = {
+                       width: this.helper.outerWidth(),
+                       height: this.helper.outerHeight()
+               };
+       },
+
+       _setContainment: function() {
+
+               var o = this.options;
+               if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
+               if(o.containment == 'document' || o.containment == 'window') this.containment = [
+                       (o.containment == 'document' ? 0 : $(window).scrollLeft()) - this.offset.relative.left - this.offset.parent.left,
+                       (o.containment == 'document' ? 0 : $(window).scrollTop()) - this.offset.relative.top - this.offset.parent.top,
+                       (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
+                       (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+               ];
+
+               if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
+                       var ce = $(o.containment)[0]; if(!ce) return;
+                       var co = $(o.containment).offset();
+                       var over = ($(ce).css("overflow") != 'hidden');
+
+                       this.containment = [
+                               co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
+                               co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
+                               co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
+                               co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
+                       ];
+               } else if(o.containment.constructor == Array) {
+                       this.containment = o.containment;
+               }
+
+       },
+
+       _convertPositionTo: function(d, pos) {
+
+               if(!pos) pos = this.position;
+               var mod = d == "absolute" ? 1 : -1;
+               var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+               return {
+                       top: (
+                               pos.top                                                                                                                                 // The absolute mouse position
+                               + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
+                               + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
+                               - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+                       ),
+                       left: (
+                               pos.left                                                                                                                                // The absolute mouse position
+                               + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
+                               + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
+                               - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+                       )
+               };
+
+       },
+
+       _generatePosition: function(event) {
+
+               var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+               var pageX = event.pageX;
+               var pageY = event.pageY;
+
+               /*
+                * - Position constraining -
+                * Constrain the position to a mix of grid, containment.
+                */
+
+               if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+
+                       if(this.containment) {
+                               if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
+                               if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
+                               if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
+                               if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
+                       }
+
+                       if(o.grid) {
+                               var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
+                               pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+                               var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
+                               pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+                       }
+
+               }
+
+               return {
+                       top: (
+                               pageY                                                                                                                           // The absolute mouse position
+                               - this.offset.click.top                                                                                                 // Click offset (relative to the element)
+                               - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
+                               - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
+                               + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+                       ),
+                       left: (
+                               pageX                                                                                                                           // The absolute mouse position
+                               - this.offset.click.left                                                                                                // Click offset (relative to the element)
+                               - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
+                               - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
+                               + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+                       )
+               };
+
+       },
+
+       _clear: function() {
+               this.helper.removeClass("ui-draggable-dragging");
+               if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
+               //if($.ui.ddmanager) $.ui.ddmanager.current = null;
+               this.helper = null;
+               this.cancelHelperRemoval = false;
+       },
+
+       // From now on bulk stuff - mainly helpers
+
+       _trigger: function(type, event, ui) {
+               ui = ui || this._uiHash();
+               $.ui.plugin.call(this, type, [event, ui]);
+               if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
+               return $.Widget.prototype._trigger.call(this, type, event, ui);
+       },
+
+       plugins: {},
+
+       _uiHash: function(event) {
+               return {
+                       helper: this.helper,
+                       position: this.position,
+                       originalPosition: this.originalPosition,
+                       offset: this.positionAbs
+               };
+       }
+
+});
+
+$.extend($.ui.draggable, {
+       version: "1.8.12"
+});
+
+$.ui.plugin.add("draggable", "connectToSortable", {
+       start: function(event, ui) {
+
+               var inst = $(this).data("draggable"), o = inst.options,
+                       uiSortable = $.extend({}, ui, { item: inst.element });
+               inst.sortables = [];
+               $(o.connectToSortable).each(function() {
+                       var sortable = $.data(this, 'sortable');
+                       if (sortable && !sortable.options.disabled) {
+                               inst.sortables.push({
+                                       instance: sortable,
+                                       shouldRevert: sortable.options.revert
+                               });
+                               sortable.refreshPositions();    // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
+                               sortable._trigger("activate", event, uiSortable);
+                       }
+               });
+
+       },
+       stop: function(event, ui) {
+
+               //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
+               var inst = $(this).data("draggable"),
+                       uiSortable = $.extend({}, ui, { item: inst.element });
+
+               $.each(inst.sortables, function() {
+                       if(this.instance.isOver) {
+
+                               this.instance.isOver = 0;
+
+                               inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
+                               this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
+
+                               //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
+                               if(this.shouldRevert) this.instance.options.revert = true;
+
+                               //Trigger the stop of the sortable
+                               this.instance._mouseStop(event);
+
+                               this.instance.options.helper = this.instance.options._helper;
+
+                               //If the helper has been the original item, restore properties in the sortable
+                               if(inst.options.helper == 'original')
+                                       this.instance.currentItem.css({ top: 'auto', left: 'auto' });
+
+                       } else {
+                               this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
+                               this.instance._trigger("deactivate", event, uiSortable);
+                       }
+
+               });
+
+       },
+       drag: function(event, ui) {
+
+               var inst = $(this).data("draggable"), self = this;
+
+               var checkPos = function(o) {
+                       var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
+                       var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
+                       var itemHeight = o.height, itemWidth = o.width;
+                       var itemTop = o.top, itemLeft = o.left;
+
+                       return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
+               };
+
+               $.each(inst.sortables, function(i) {
+                       
+                       //Copy over some variables to allow calling the sortable's native _intersectsWith
+                       this.instance.positionAbs = inst.positionAbs;
+                       this.instance.helperProportions = inst.helperProportions;
+                       this.instance.offset.click = inst.offset.click;
+                       
+                       if(this.instance._intersectsWith(this.instance.containerCache)) {
+
+                               //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
+                               if(!this.instance.isOver) {
+
+                                       this.instance.isOver = 1;
+                                       //Now we fake the start of dragging for the sortable instance,
+                                       //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
+                                       //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
+                                       this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
+                                       this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
+                                       this.instance.options.helper = function() { return ui.helper[0]; };
+
+                                       event.target = this.instance.currentItem[0];
+                                       this.instance._mouseCapture(event, true);
+                                       this.instance._mouseStart(event, true, true);
+
+                                       //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
+                                       this.instance.offset.click.top = inst.offset.click.top;
+                                       this.instance.offset.click.left = inst.offset.click.left;
+                                       this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
+                                       this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
+
+                                       inst._trigger("toSortable", event);
+                                       inst.dropped = this.instance.element; //draggable revert needs that
+                                       //hack so receive/update callbacks work (mostly)
+                                       inst.currentItem = inst.element;
+                                       this.instance.fromOutside = inst;
+
+                               }
+
+                               //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
+                               if(this.instance.currentItem) this.instance._mouseDrag(event);
+
+                       } else {
+
+                               //If it doesn't intersect with the sortable, and it intersected before,
+                               //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
+                               if(this.instance.isOver) {
+
+                                       this.instance.isOver = 0;
+                                       this.instance.cancelHelperRemoval = true;
+                                       
+                                       //Prevent reverting on this forced stop
+                                       this.instance.options.revert = false;
+                                       
+                                       // The out event needs to be triggered independently
+                                       this.instance._trigger('out', event, this.instance._uiHash(this.instance));
+                                       
+                                       this.instance._mouseStop(event, true);
+                                       this.instance.options.helper = this.instance.options._helper;
+
+                                       //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
+                                       this.instance.currentItem.remove();
+                                       if(this.instance.placeholder) this.instance.placeholder.remove();
+
+                                       inst._trigger("fromSortable", event);
+                                       inst.dropped = false; //draggable revert needs that
+                               }
+
+                       };
+
+               });
+
+       }
+});
+
+$.ui.plugin.add("draggable", "cursor", {
+       start: function(event, ui) {
+               var t = $('body'), o = $(this).data('draggable').options;
+               if (t.css("cursor")) o._cursor = t.css("cursor");
+               t.css("cursor", o.cursor);
+       },
+       stop: function(event, ui) {
+               var o = $(this).data('draggable').options;
+               if (o._cursor) $('body').css("cursor", o._cursor);
+       }
+});
+
+$.ui.plugin.add("draggable", "iframeFix", {
+       start: function(event, ui) {
+               var o = $(this).data('draggable').options;
+               $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
+                       $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
+                       .css({
+                               width: this.offsetWidth+"px", height: this.offsetHeight+"px",
+                               position: "absolute", opacity: "0.001", zIndex: 1000
+                       })
+                       .css($(this).offset())
+                       .appendTo("body");
+               });
+       },
+       stop: function(event, ui) {
+               $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
+       }
+});
+
+$.ui.plugin.add("draggable", "opacity", {
+       start: function(event, ui) {
+               var t = $(ui.helper), o = $(this).data('draggable').options;
+               if(t.css("opacity")) o._opacity = t.css("opacity");
+               t.css('opacity', o.opacity);
+       },
+       stop: function(event, ui) {
+               var o = $(this).data('draggable').options;
+               if(o._opacity) $(ui.helper).css('opacity', o._opacity);
+       }
+});
+
+$.ui.plugin.add("draggable", "scroll", {
+       start: function(event, ui) {
+               var i = $(this).data("draggable");
+               if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
+       },
+       drag: function(event, ui) {
+
+               var i = $(this).data("draggable"), o = i.options, scrolled = false;
+
+               if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
+
+                       if(!o.axis || o.axis != 'x') {
+                               if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
+                                       i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
+                               else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
+                                       i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
+                       }
+
+                       if(!o.axis || o.axis != 'y') {
+                               if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
+                                       i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
+                               else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
+                                       i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
+                       }
+
+               } else {
+
+                       if(!o.axis || o.axis != 'x') {
+                               if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
+                                       scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+                               else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
+                                       scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+                       }
+
+                       if(!o.axis || o.axis != 'y') {
+                               if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+                               else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+                       }
+
+               }
+
+               if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
+                       $.ui.ddmanager.prepareOffsets(i, event);
+
+       }
+});
+
+$.ui.plugin.add("draggable", "snap", {
+       start: function(event, ui) {
+
+               var i = $(this).data("draggable"), o = i.options;
+               i.snapElements = [];
+
+               $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
+                       var $t = $(this); var $o = $t.offset();
+                       if(this != i.element[0]) i.snapElements.push({
+                               item: this,
+                               width: $t.outerWidth(), height: $t.outerHeight(),
+                               top: $o.top, left: $o.left
+                       });
+               });
+
+       },
+       drag: function(event, ui) {
+
+               var inst = $(this).data("draggable"), o = inst.options;
+               var d = o.snapTolerance;
+
+               var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
+                       y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
+
+               for (var i = inst.snapElements.length - 1; i >= 0; i--){
+
+                       var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
+                               t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
+
+                       //Yes, I know, this is insane ;)
+                       if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
+                               if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+                               inst.snapElements[i].snapping = false;
+                               continue;
+                       }
+
+                       if(o.snapMode != 'inner') {
+                               var ts = Math.abs(t - y2) <= d;
+                               var bs = Math.abs(b - y1) <= d;
+                               var ls = Math.abs(l - x2) <= d;
+                               var rs = Math.abs(r - x1) <= d;
+                               if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+                               if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
+                               if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
+                               if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
+                       }
+
+                       var first = (ts || bs || ls || rs);
+
+                       if(o.snapMode != 'outer') {
+                               var ts = Math.abs(t - y1) <= d;
+                               var bs = Math.abs(b - y2) <= d;
+                               var ls = Math.abs(l - x1) <= d;
+                               var rs = Math.abs(r - x2) <= d;
+                               if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
+                               if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+                               if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
+                               if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
+                       }
+
+                       if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
+                               (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+                       inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
+
+               };
+
+       }
+});
+
+$.ui.plugin.add("draggable", "stack", {
+       start: function(event, ui) {
+
+               var o = $(this).data("draggable").options;
+
+               var group = $.makeArray($(o.stack)).sort(function(a,b) {
+                       return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
+               });
+               if (!group.length) { return; }
+               
+               var min = parseInt(group[0].style.zIndex) || 0;
+               $(group).each(function(i) {
+                       this.style.zIndex = min + i;
+               });
+
+               this[0].style.zIndex = min + group.length;
+
+       }
+});
+
+$.ui.plugin.add("draggable", "zIndex", {
+       start: function(event, ui) {
+               var t = $(ui.helper), o = $(this).data("draggable").options;
+               if(t.css("zIndex")) o._zIndex = t.css("zIndex");
+               t.css('zIndex', o.zIndex);
+       },
+       stop: function(event, ui) {
+               var o = $(this).data("draggable").options;
+               if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
+       }
+});
+
+})(jQuery);
+/*
+ * jQuery UI Droppable 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Droppables
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.widget.js
+ *     jquery.ui.mouse.js
+ *     jquery.ui.draggable.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.droppable", {
+       widgetEventPrefix: "drop",
+       options: {
+               accept: '*',
+               activeClass: false,
+               addClasses: true,
+               greedy: false,
+               hoverClass: false,
+               scope: 'default',
+               tolerance: 'intersect'
+       },
+       _create: function() {
+
+               var o = this.options, accept = o.accept;
+               this.isover = 0; this.isout = 1;
+
+               this.accept = $.isFunction(accept) ? accept : function(d) {
+                       return d.is(accept);
+               };
+
+               //Store the droppable's proportions
+               this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
+
+               // Add the reference and positions to the manager
+               $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
+               $.ui.ddmanager.droppables[o.scope].push(this);
+
+               (o.addClasses && this.element.addClass("ui-droppable"));
+
+       },
+
+       destroy: function() {
+               var drop = $.ui.ddmanager.droppables[this.options.scope];
+               for ( var i = 0; i < drop.length; i++ )
+                       if ( drop[i] == this )
+                               drop.splice(i, 1);
+
+               this.element
+                       .removeClass("ui-droppable ui-droppable-disabled")
+                       .removeData("droppable")
+                       .unbind(".droppable");
+
+               return this;
+       },
+
+       _setOption: function(key, value) {
+
+               if(key == 'accept') {
+                       this.accept = $.isFunction(value) ? value : function(d) {
+                               return d.is(value);
+                       };
+               }
+               $.Widget.prototype._setOption.apply(this, arguments);
+       },
+
+       _activate: function(event) {
+               var draggable = $.ui.ddmanager.current;
+               if(this.options.activeClass) this.element.addClass(this.options.activeClass);
+               (draggable && this._trigger('activate', event, this.ui(draggable)));
+       },
+
+       _deactivate: function(event) {
+               var draggable = $.ui.ddmanager.current;
+               if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
+               (draggable && this._trigger('deactivate', event, this.ui(draggable)));
+       },
+
+       _over: function(event) {
+
+               var draggable = $.ui.ddmanager.current;
+               if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
+
+               if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+                       if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
+                       this._trigger('over', event, this.ui(draggable));
+               }
+
+       },
+
+       _out: function(event) {
+
+               var draggable = $.ui.ddmanager.current;
+               if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
+
+               if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+                       if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
+                       this._trigger('out', event, this.ui(draggable));
+               }
+
+       },
+
+       _drop: function(event,custom) {
+
+               var draggable = custom || $.ui.ddmanager.current;
+               if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
+
+               var childrenIntersection = false;
+               this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
+                       var inst = $.data(this, 'droppable');
+                       if(
+                               inst.options.greedy
+                               && !inst.options.disabled
+                               && inst.options.scope == draggable.options.scope
+                               && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
+                               && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
+                       ) { childrenIntersection = true; return false; }
+               });
+               if(childrenIntersection) return false;
+
+               if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+                       if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
+                       if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
+                       this._trigger('drop', event, this.ui(draggable));
+                       return this.element;
+               }
+
+               return false;
+
+       },
+
+       ui: function(c) {
+               return {
+                       draggable: (c.currentItem || c.element),
+                       helper: c.helper,
+                       position: c.position,
+                       offset: c.positionAbs
+               };
+       }
+
+});
+
+$.extend($.ui.droppable, {
+       version: "1.8.12"
+});
+
+$.ui.intersect = function(draggable, droppable, toleranceMode) {
+
+       if (!droppable.offset) return false;
+
+       var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
+               y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
+       var l = droppable.offset.left, r = l + droppable.proportions.width,
+               t = droppable.offset.top, b = t + droppable.proportions.height;
+
+       switch (toleranceMode) {
+               case 'fit':
+                       return (l <= x1 && x2 <= r
+                               && t <= y1 && y2 <= b);
+                       break;
+               case 'intersect':
+                       return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
+                               && x2 - (draggable.helperProportions.width / 2) < r // Left Half
+                               && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
+                               && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
+                       break;
+               case 'pointer':
+                       var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
+                               draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
+                               isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
+                       return isOver;
+                       break;
+               case 'touch':
+                       return (
+                                       (y1 >= t && y1 <= b) || // Top edge touching
+                                       (y2 >= t && y2 <= b) || // Bottom edge touching
+                                       (y1 < t && y2 > b)              // Surrounded vertically
+                               ) && (
+                                       (x1 >= l && x1 <= r) || // Left edge touching
+                                       (x2 >= l && x2 <= r) || // Right edge touching
+                                       (x1 < l && x2 > r)              // Surrounded horizontally
+                               );
+                       break;
+               default:
+                       return false;
+                       break;
+               }
+
+};
+
+/*
+       This manager tracks offsets of draggables and droppables
+*/
+$.ui.ddmanager = {
+       current: null,
+       droppables: { 'default': [] },
+       prepareOffsets: function(t, event) {
+
+               var m = $.ui.ddmanager.droppables[t.options.scope] || [];
+               var type = event ? event.type : null; // workaround for #2317
+               var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
+
+               droppablesLoop: for (var i = 0; i < m.length; i++) {
+
+                       if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;   //No disabled and non-accepted
+                       for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
+                       m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;                                                                       //If the element is not visible, continue
+
+                       if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
+
+                       m[i].offset = m[i].element.offset();
+                       m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
+
+               }
+
+       },
+       drop: function(draggable, event) {
+
+               var dropped = false;
+               $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
+
+                       if(!this.options) return;
+                       if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
+                               dropped = dropped || this._drop.call(this, event);
+
+                       if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+                               this.isout = 1; this.isover = 0;
+                               this._deactivate.call(this, event);
+                       }
+
+               });
+               return dropped;
+
+       },
+       drag: function(draggable, event) {
+
+               //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
+               if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
+
+               //Run through all droppables and check their positions based on specific tolerance options
+               $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
+
+                       if(this.options.disabled || this.greedyChild || !this.visible) return;
+                       var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
+
+                       var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
+                       if(!c) return;
+
+                       var parentInstance;
+                       if (this.options.greedy) {
+                               var parent = this.element.parents(':data(droppable):eq(0)');
+                               if (parent.length) {
+                                       parentInstance = $.data(parent[0], 'droppable');
+                                       parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
+                               }
+                       }
+
+                       // we just moved into a greedy child
+                       if (parentInstance && c == 'isover') {
+                               parentInstance['isover'] = 0;
+                               parentInstance['isout'] = 1;
+                               parentInstance._out.call(parentInstance, event);
+                       }
+
+                       this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
+                       this[c == "isover" ? "_over" : "_out"].call(this, event);
+
+                       // we just moved out of a greedy child
+                       if (parentInstance && c == 'isout') {
+                               parentInstance['isout'] = 0;
+                               parentInstance['isover'] = 1;
+                               parentInstance._over.call(parentInstance, event);
+                       }
+               });
+
+       }
+};
+
+})(jQuery);
+/*
+ * jQuery UI Resizable 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.mouse.js
+ *     jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.resizable", $.ui.mouse, {
+       widgetEventPrefix: "resize",
+       options: {
+               alsoResize: false,
+               animate: false,
+               animateDuration: "slow",
+               animateEasing: "swing",
+               aspectRatio: false,
+               autoHide: false,
+               containment: false,
+               ghost: false,
+               grid: false,
+               handles: "e,s,se",
+               helper: false,
+               maxHeight: null,
+               maxWidth: null,
+               minHeight: 10,
+               minWidth: 10,
+               zIndex: 1000
+       },
+       _create: function() {
+
+               var self = this, o = this.options;
+               this.element.addClass("ui-resizable");
+
+               $.extend(this, {
+                       _aspectRatio: !!(o.aspectRatio),
+                       aspectRatio: o.aspectRatio,
+                       originalElement: this.element,
+                       _proportionallyResizeElements: [],
+                       _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
+               });
+
+               //Wrap the element if it cannot hold child nodes
+               if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
+
+                       //Opera fix for relative positioning
+                       if (/relative/.test(this.element.css('position')) && $.browser.opera)
+                               this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+                       //Create a wrapper element and set the wrapper to the new current internal element
+                       this.element.wrap(
+                               $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
+                                       position: this.element.css('position'),
+                                       width: this.element.outerWidth(),
+                                       height: this.element.outerHeight(),
+                                       top: this.element.css('top'),
+                                       left: this.element.css('left')
+                               })
+                       );
+
+                       //Overwrite the original this.element
+                       this.element = this.element.parent().data(
+                               "resizable", this.element.data('resizable')
+                       );
+
+                       this.elementIsWrapper = true;
+
+                       //Move margins to the wrapper
+                       this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
+                       this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
+
+                       //Prevent Safari textarea resize
+                       this.originalResizeStyle = this.originalElement.css('resize');
+                       this.originalElement.css('resize', 'none');
+
+                       //Push the actual element to our proportionallyResize internal array
+                       this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
+
+                       // avoid IE jump (hard set the margin)
+                       this.originalElement.css({ margin: this.originalElement.css('margin') });
+
+                       // fix handlers offset
+                       this._proportionallyResize();
+
+               }
+
+               this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
+               if(this.handles.constructor == String) {
+
+                       if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
+                       var n = this.handles.split(","); this.handles = {};
+
+                       for(var i = 0; i < n.length; i++) {
+
+                               var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
+                               var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
+
+                               // increase zIndex of sw, se, ne, nw axis
+                               //TODO : this modifies original option
+                               if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
+
+                               //TODO : What's going on here?
+                               if ('se' == handle) {
+                                       axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
+                               };
+
+                               //Insert into internal handles object and append to element
+                               this.handles[handle] = '.ui-resizable-'+handle;
+                               this.element.append(axis);
+                       }
+
+               }
+
+               this._renderAxis = function(target) {
+
+                       target = target || this.element;
+
+                       for(var i in this.handles) {
+
+                               if(this.handles[i].constructor == String)
+                                       this.handles[i] = $(this.handles[i], this.element).show();
+
+                               //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
+                               if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
+
+                                       var axis = $(this.handles[i], this.element), padWrapper = 0;
+
+                                       //Checking the correct pad and border
+                                       padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+
+                                       //The padding type i have to apply...
+                                       var padPos = [ 'padding',
+                                               /ne|nw|n/.test(i) ? 'Top' :
+                                               /se|sw|s/.test(i) ? 'Bottom' :
+                                               /^e$/.test(i) ? 'Right' : 'Left' ].join("");
+
+                                       target.css(padPos, padWrapper);
+
+                                       this._proportionallyResize();
+
+                               }
+
+                               //TODO: What's that good for? There's not anything to be executed left
+                               if(!$(this.handles[i]).length)
+                                       continue;
+
+                       }
+               };
+
+               //TODO: make renderAxis a prototype function
+               this._renderAxis(this.element);
+
+               this._handles = $('.ui-resizable-handle', this.element)
+                       .disableSelection();
+
+               //Matching axis name
+               this._handles.mouseover(function() {
+                       if (!self.resizing) {
+                               if (this.className)
+                                       var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+                               //Axis, default = se
+                               self.axis = axis && axis[1] ? axis[1] : 'se';
+                       }
+               });
+
+               //If we want to auto hide the elements
+               if (o.autoHide) {
+                       this._handles.hide();
+                       $(this.element)
+                               .addClass("ui-resizable-autohide")
+                               .hover(function() {
+                                       $(this).removeClass("ui-resizable-autohide");
+                                       self._handles.show();
+                               },
+                               function(){
+                                       if (!self.resizing) {
+                                               $(this).addClass("ui-resizable-autohide");
+                                               self._handles.hide();
+                                       }
+                               });
+               }
+
+               //Initialize the mouse interaction
+               this._mouseInit();
+
+       },
+
+       destroy: function() {
+
+               this._mouseDestroy();
+
+               var _destroy = function(exp) {
+                       $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
+                               .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
+               };
+
+               //TODO: Unwrap at same DOM position
+               if (this.elementIsWrapper) {
+                       _destroy(this.element);
+                       var wrapper = this.element;
+                       wrapper.after(
+                               this.originalElement.css({
+                                       position: wrapper.css('position'),
+                                       width: wrapper.outerWidth(),
+                                       height: wrapper.outerHeight(),
+                                       top: wrapper.css('top'),
+                                       left: wrapper.css('left')
+                               })
+                       ).remove();
+               }
+
+               this.originalElement.css('resize', this.originalResizeStyle);
+               _destroy(this.originalElement);
+
+               return this;
+       },
+
+       _mouseCapture: function(event) {
+               var handle = false;
+               for (var i in this.handles) {
+                       if ($(this.handles[i])[0] == event.target) {
+                               handle = true;
+                       }
+               }
+
+               return !this.options.disabled && handle;
+       },
+
+       _mouseStart: function(event) {
+
+               var o = this.options, iniPos = this.element.position(), el = this.element;
+
+               this.resizing = true;
+               this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
+
+               // bugfix for http://dev.jquery.com/ticket/1749
+               if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
+                       el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
+               }
+
+               //Opera fixing relative position
+               if ($.browser.opera && (/relative/).test(el.css('position')))
+                       el.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+               this._renderProxy();
+
+               var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
+
+               if (o.containment) {
+                       curleft += $(o.containment).scrollLeft() || 0;
+                       curtop += $(o.containment).scrollTop() || 0;
+               }
+
+               //Store needed variables
+               this.offset = this.helper.offset();
+               this.position = { left: curleft, top: curtop };
+               this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+               this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+               this.originalPosition = { left: curleft, top: curtop };
+               this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
+               this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+               //Aspect Ratio
+               this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
+
+           var cursor = $('.ui-resizable-' + this.axis).css('cursor');
+           $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
+
+               el.addClass("ui-resizable-resizing");
+               this._propagate("start", event);
+               return true;
+       },
+
+       _mouseDrag: function(event) {
+
+               //Increase performance, avoid regex
+               var el = this.helper, o = this.options, props = {},
+                       self = this, smp = this.originalMousePosition, a = this.axis;
+
+               var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
+               var trigger = this._change[a];
+               if (!trigger) return false;
+
+               // Calculate the attrs that will be change
+               var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
+
+               if (this._aspectRatio || event.shiftKey)
+                       data = this._updateRatio(data, event);
+
+               data = this._respectSize(data, event);
+
+               // plugins callbacks need to be called first
+               this._propagate("resize", event);
+
+               el.css({
+                       top: this.position.top + "px", left: this.position.left + "px",
+                       width: this.size.width + "px", height: this.size.height + "px"
+               });
+
+               if (!this._helper && this._proportionallyResizeElements.length)
+                       this._proportionallyResize();
+
+               this._updateCache(data);
+
+               // calling the user callback at the end
+               this._trigger('resize', event, this.ui());
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+
+               this.resizing = false;
+               var o = this.options, self = this;
+
+               if(this._helper) {
+                       var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+                               soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+                               soffsetw = ista ? 0 : self.sizeDiff.width;
+
+                       var s = { width: (self.helper.width()  - soffsetw), height: (self.helper.height() - soffseth) },
+                               left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+                               top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+                       if (!o.animate)
+                               this.element.css($.extend(s, { top: top, left: left }));
+
+                       self.helper.height(self.size.height);
+                       self.helper.width(self.size.width);
+
+                       if (this._helper && !o.animate) this._proportionallyResize();
+               }
+
+               $('body').css('cursor', 'auto');
+
+               this.element.removeClass("ui-resizable-resizing");
+
+               this._propagate("stop", event);
+
+               if (this._helper) this.helper.remove();
+               return false;
+
+       },
+
+       _updateCache: function(data) {
+               var o = this.options;
+               this.offset = this.helper.offset();
+               if (isNumber(data.left)) this.position.left = data.left;
+               if (isNumber(data.top)) this.position.top = data.top;
+               if (isNumber(data.height)) this.size.height = data.height;
+               if (isNumber(data.width)) this.size.width = data.width;
+       },
+
+       _updateRatio: function(data, event) {
+
+               var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
+
+               if (data.height) data.width = (csize.height * this.aspectRatio);
+               else if (data.width) data.height = (csize.width / this.aspectRatio);
+
+               if (a == 'sw') {
+                       data.left = cpos.left + (csize.width - data.width);
+                       data.top = null;
+               }
+               if (a == 'nw') {
+                       data.top = cpos.top + (csize.height - data.height);
+                       data.left = cpos.left + (csize.width - data.width);
+               }
+
+               return data;
+       },
+
+       _respectSize: function(data, event) {
+
+               var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
+                               ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
+                                       isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
+
+               if (isminw) data.width = o.minWidth;
+               if (isminh) data.height = o.minHeight;
+               if (ismaxw) data.width = o.maxWidth;
+               if (ismaxh) data.height = o.maxHeight;
+
+               var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
+               var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+
+               if (isminw && cw) data.left = dw - o.minWidth;
+               if (ismaxw && cw) data.left = dw - o.maxWidth;
+               if (isminh && ch)       data.top = dh - o.minHeight;
+               if (ismaxh && ch)       data.top = dh - o.maxHeight;
+
+               // fixing jump error on top/left - bug #2330
+               var isNotwh = !data.width && !data.height;
+               if (isNotwh && !data.left && data.top) data.top = null;
+               else if (isNotwh && !data.top && data.left) data.left = null;
+
+               return data;
+       },
+
+       _proportionallyResize: function() {
+
+               var o = this.options;
+               if (!this._proportionallyResizeElements.length) return;
+               var element = this.helper || this.element;
+
+               for (var i=0; i < this._proportionallyResizeElements.length; i++) {
+
+                       var prel = this._proportionallyResizeElements[i];
+
+                       if (!this.borderDif) {
+                               var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
+                                       p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
+
+                               this.borderDif = $.map(b, function(v, i) {
+                                       var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
+                                       return border + padding;
+                               });
+                       }
+
+                       if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
+                               continue;
+
+                       prel.css({
+                               height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
+                               width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
+                       });
+
+               };
+
+       },
+
+       _renderProxy: function() {
+
+               var el = this.element, o = this.options;
+               this.elementOffset = el.offset();
+
+               if(this._helper) {
+
+                       this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
+
+                       // fix ie6 offset TODO: This seems broken
+                       var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
+                       pxyoffset = ( ie6 ? 2 : -1 );
+
+                       this.helper.addClass(this._helper).css({
+                               width: this.element.outerWidth() + pxyoffset,
+                               height: this.element.outerHeight() + pxyoffset,
+                               position: 'absolute',
+                               left: this.elementOffset.left - ie6offset +'px',
+                               top: this.elementOffset.top - ie6offset +'px',
+                               zIndex: ++o.zIndex //TODO: Don't modify option
+                       });
+
+                       this.helper
+                               .appendTo("body")
+                               .disableSelection();
+
+               } else {
+                       this.helper = this.element;
+               }
+
+       },
+
+       _change: {
+               e: function(event, dx, dy) {
+                       return { width: this.originalSize.width + dx };
+               },
+               w: function(event, dx, dy) {
+                       var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+                       return { left: sp.left + dx, width: cs.width - dx };
+               },
+               n: function(event, dx, dy) {
+                       var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+                       return { top: sp.top + dy, height: cs.height - dy };
+               },
+               s: function(event, dx, dy) {
+                       return { height: this.originalSize.height + dy };
+               },
+               se: function(event, dx, dy) {
+                       return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+               },
+               sw: function(event, dx, dy) {
+                       return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+               },
+               ne: function(event, dx, dy) {
+                       return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+               },
+               nw: function(event, dx, dy) {
+                       return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+               }
+       },
+
+       _propagate: function(n, event) {
+               $.ui.plugin.call(this, n, [event, this.ui()]);
+               (n != "resize" && this._trigger(n, event, this.ui()));
+       },
+
+       plugins: {},
+
+       ui: function() {
+               return {
+                       originalElement: this.originalElement,
+                       element: this.element,
+                       helper: this.helper,
+                       position: this.position,
+                       size: this.size,
+                       originalSize: this.originalSize,
+                       originalPosition: this.originalPosition
+               };
+       }
+
+});
+
+$.extend($.ui.resizable, {
+       version: "1.8.12"
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "alsoResize", {
+
+       start: function (event, ui) {
+               var self = $(this).data("resizable"), o = self.options;
+
+               var _store = function (exp) {
+                       $(exp).each(function() {
+                               var el = $(this);
+                               el.data("resizable-alsoresize", {
+                                       width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
+                                       left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
+                                       position: el.css('position') // to reset Opera on stop()
+                               });
+                       });
+               };
+
+               if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
+                       if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
+                       else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
+               }else{
+                       _store(o.alsoResize);
+               }
+       },
+
+       resize: function (event, ui) {
+               var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
+
+               var delta = {
+                       height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
+                       top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
+               },
+
+               _alsoResize = function (exp, c) {
+                       $(exp).each(function() {
+                               var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 
+                                       css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
+
+                               $.each(css, function (i, prop) {
+                                       var sum = (start[prop]||0) + (delta[prop]||0);
+                                       if (sum && sum >= 0)
+                                               style[prop] = sum || null;
+                               });
+
+                               // Opera fixing relative position
+                               if ($.browser.opera && /relative/.test(el.css('position'))) {
+                                       self._revertToRelativePosition = true;
+                                       el.css({ position: 'absolute', top: 'auto', left: 'auto' });
+                               }
+
+                               el.css(style);
+                       });
+               };
+
+               if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
+                       $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
+               }else{
+                       _alsoResize(o.alsoResize);
+               }
+       },
+
+       stop: function (event, ui) {
+               var self = $(this).data("resizable"), o = self.options;
+
+               var _reset = function (exp) {
+                       $(exp).each(function() {
+                               var el = $(this);
+                               // reset position for Opera - no need to verify it was changed
+                               el.css({ position: el.data("resizable-alsoresize").position });
+                       });
+               };
+
+               if (self._revertToRelativePosition) {
+                       self._revertToRelativePosition = false;
+                       if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
+                               $.each(o.alsoResize, function (exp) { _reset(exp); });
+                       }else{
+                               _reset(o.alsoResize);
+                       }
+               }
+
+               $(this).removeData("resizable-alsoresize");
+       }
+});
+
+$.ui.plugin.add("resizable", "animate", {
+
+       stop: function(event, ui) {
+               var self = $(this).data("resizable"), o = self.options;
+
+               var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+                                       soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+                                               soffsetw = ista ? 0 : self.sizeDiff.width;
+
+               var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+                                       left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+                                               top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+               self.element.animate(
+                       $.extend(style, top && left ? { top: top, left: left } : {}), {
+                               duration: o.animateDuration,
+                               easing: o.animateEasing,
+                               step: function() {
+
+                                       var data = {
+                                               width: parseInt(self.element.css('width'), 10),
+                                               height: parseInt(self.element.css('height'), 10),
+                                               top: parseInt(self.element.css('top'), 10),
+                                               left: parseInt(self.element.css('left'), 10)
+                                       };
+
+                                       if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
+
+                                       // propagating resize, and updating values for each animation step
+                                       self._updateCache(data);
+                                       self._propagate("resize", event);
+
+                               }
+                       }
+               );
+       }
+
+});
+
+$.ui.plugin.add("resizable", "containment", {
+
+       start: function(event, ui) {
+               var self = $(this).data("resizable"), o = self.options, el = self.element;
+               var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
+               if (!ce) return;
+
+               self.containerElement = $(ce);
+
+               if (/document/.test(oc) || oc == document) {
+                       self.containerOffset = { left: 0, top: 0 };
+                       self.containerPosition = { left: 0, top: 0 };
+
+                       self.parentData = {
+                               element: $(document), left: 0, top: 0,
+                               width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
+                       };
+               }
+
+               // i'm a node, so compute top, left, right, bottom
+               else {
+                       var element = $(ce), p = [];
+                       $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
+
+                       self.containerOffset = element.offset();
+                       self.containerPosition = element.position();
+                       self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
+
+                       var co = self.containerOffset, ch = self.containerSize.height,  cw = self.containerSize.width,
+                                               width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
+
+                       self.parentData = {
+                               element: ce, left: co.left, top: co.top, width: width, height: height
+                       };
+               }
+       },
+
+       resize: function(event, ui) {
+               var self = $(this).data("resizable"), o = self.options,
+                               ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
+                               pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
+
+               if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
+
+               if (cp.left < (self._helper ? co.left : 0)) {
+                       self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
+                       if (pRatio) self.size.height = self.size.width / o.aspectRatio;
+                       self.position.left = o.helper ? co.left : 0;
+               }
+
+               if (cp.top < (self._helper ? co.top : 0)) {
+                       self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
+                       if (pRatio) self.size.width = self.size.height * o.aspectRatio;
+                       self.position.top = self._helper ? co.top : 0;
+               }
+
+               self.offset.left = self.parentData.left+self.position.left;
+               self.offset.top = self.parentData.top+self.position.top;
+
+               var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
+                                       hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
+
+               var isParent = self.containerElement.get(0) == self.element.parent().get(0),
+                   isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
+
+               if(isParent && isOffsetRelative) woset -= self.parentData.left;
+
+               if (woset + self.size.width >= self.parentData.width) {
+                       self.size.width = self.parentData.width - woset;
+                       if (pRatio) self.size.height = self.size.width / self.aspectRatio;
+               }
+
+               if (hoset + self.size.height >= self.parentData.height) {
+                       self.size.height = self.parentData.height - hoset;
+                       if (pRatio) self.size.width = self.size.height * self.aspectRatio;
+               }
+       },
+
+       stop: function(event, ui){
+               var self = $(this).data("resizable"), o = self.options, cp = self.position,
+                               co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
+
+               var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
+
+               if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
+                       $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+               if (self._helper && !o.animate && (/static/).test(ce.css('position')))
+                       $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+       }
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+
+       start: function(event, ui) {
+
+               var self = $(this).data("resizable"), o = self.options, cs = self.size;
+
+               self.ghost = self.originalElement.clone();
+               self.ghost
+                       .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
+                       .addClass('ui-resizable-ghost')
+                       .addClass(typeof o.ghost == 'string' ? o.ghost : '');
+
+               self.ghost.appendTo(self.helper);
+
+       },
+
+       resize: function(event, ui){
+               var self = $(this).data("resizable"), o = self.options;
+               if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
+       },
+
+       stop: function(event, ui){
+               var self = $(this).data("resizable"), o = self.options;
+               if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
+       }
+
+});
+
+$.ui.plugin.add("resizable", "grid", {
+
+       resize: function(event, ui) {
+               var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
+               o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
+               var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
+
+               if (/^(se|s|e)$/.test(a)) {
+                       self.size.width = os.width + ox;
+                       self.size.height = os.height + oy;
+               }
+               else if (/^(ne)$/.test(a)) {
+                       self.size.width = os.width + ox;
+                       self.size.height = os.height + oy;
+                       self.position.top = op.top - oy;
+               }
+               else if (/^(sw)$/.test(a)) {
+                       self.size.width = os.width + ox;
+                       self.size.height = os.height + oy;
+                       self.position.left = op.left - ox;
+               }
+               else {
+                       self.size.width = os.width + ox;
+                       self.size.height = os.height + oy;
+                       self.position.top = op.top - oy;
+                       self.position.left = op.left - ox;
+               }
+       }
+
+});
+
+var num = function(v) {
+       return parseInt(v, 10) || 0;
+};
+
+var isNumber = function(value) {
+       return !isNaN(parseInt(value, 10));
+};
+
+})(jQuery);
+/*
+ * jQuery UI Selectable 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectables
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.mouse.js
+ *     jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.selectable", $.ui.mouse, {
+       options: {
+               appendTo: 'body',
+               autoRefresh: true,
+               distance: 0,
+               filter: '*',
+               tolerance: 'touch'
+       },
+       _create: function() {
+               var self = this;
+
+               this.element.addClass("ui-selectable");
+
+               this.dragged = false;
+
+               // cache selectee children based on filter
+               var selectees;
+               this.refresh = function() {
+                       selectees = $(self.options.filter, self.element[0]);
+                       selectees.each(function() {
+                               var $this = $(this);
+                               var pos = $this.offset();
+                               $.data(this, "selectable-item", {
+                                       element: this,
+                                       $element: $this,
+                                       left: pos.left,
+                                       top: pos.top,
+                                       right: pos.left + $this.outerWidth(),
+                                       bottom: pos.top + $this.outerHeight(),
+                                       startselected: false,
+                                       selected: $this.hasClass('ui-selected'),
+                                       selecting: $this.hasClass('ui-selecting'),
+                                       unselecting: $this.hasClass('ui-unselecting')
+                               });
+                       });
+               };
+               this.refresh();
+
+               this.selectees = selectees.addClass("ui-selectee");
+
+               this._mouseInit();
+
+               this.helper = $("<div class='ui-selectable-helper'></div>");
+       },
+
+       destroy: function() {
+               this.selectees
+                       .removeClass("ui-selectee")
+                       .removeData("selectable-item");
+               this.element
+                       .removeClass("ui-selectable ui-selectable-disabled")
+                       .removeData("selectable")
+                       .unbind(".selectable");
+               this._mouseDestroy();
+
+               return this;
+       },
+
+       _mouseStart: function(event) {
+               var self = this;
+
+               this.opos = [event.pageX, event.pageY];
+
+               if (this.options.disabled)
+                       return;
+
+               var options = this.options;
+
+               this.selectees = $(options.filter, this.element[0]);
+
+               this._trigger("start", event);
+
+               $(options.appendTo).append(this.helper);
+               // position helper (lasso)
+               this.helper.css({
+                       "left": event.clientX,
+                       "top": event.clientY,
+                       "width": 0,
+                       "height": 0
+               });
+
+               if (options.autoRefresh) {
+                       this.refresh();
+               }
+
+               this.selectees.filter('.ui-selected').each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.startselected = true;
+                       if (!event.metaKey) {
+                               selectee.$element.removeClass('ui-selected');
+                               selectee.selected = false;
+                               selectee.$element.addClass('ui-unselecting');
+                               selectee.unselecting = true;
+                               // selectable UNSELECTING callback
+                               self._trigger("unselecting", event, {
+                                       unselecting: selectee.element
+                               });
+                       }
+               });
+
+               $(event.target).parents().andSelf().each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       if (selectee) {
+                               var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
+                               selectee.$element
+                                       .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
+                                       .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
+                               selectee.unselecting = !doSelect;
+                               selectee.selecting = doSelect;
+                               selectee.selected = doSelect;
+                               // selectable (UN)SELECTING callback
+                               if (doSelect) {
+                                       self._trigger("selecting", event, {
+                                               selecting: selectee.element
+                                       });
+                               } else {
+                                       self._trigger("unselecting", event, {
+                                               unselecting: selectee.element
+                                       });
+                               }
+                               return false;
+                       }
+               });
+
+       },
+
+       _mouseDrag: function(event) {
+               var self = this;
+               this.dragged = true;
+
+               if (this.options.disabled)
+                       return;
+
+               var options = this.options;
+
+               var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
+               if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
+               if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
+               this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
+
+               this.selectees.each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       //prevent helper from being selected if appendTo: selectable
+                       if (!selectee || selectee.element == self.element[0])
+                               return;
+                       var hit = false;
+                       if (options.tolerance == 'touch') {
+                               hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
+                       } else if (options.tolerance == 'fit') {
+                               hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
+                       }
+
+                       if (hit) {
+                               // SELECT
+                               if (selectee.selected) {
+                                       selectee.$element.removeClass('ui-selected');
+                                       selectee.selected = false;
+                               }
+                               if (selectee.unselecting) {
+                                       selectee.$element.removeClass('ui-unselecting');
+                                       selectee.unselecting = false;
+                               }
+                               if (!selectee.selecting) {
+                                       selectee.$element.addClass('ui-selecting');
+                                       selectee.selecting = true;
+                                       // selectable SELECTING callback
+                                       self._trigger("selecting", event, {
+                                               selecting: selectee.element
+                                       });
+                               }
+                       } else {
+                               // UNSELECT
+                               if (selectee.selecting) {
+                                       if (event.metaKey && selectee.startselected) {
+                                               selectee.$element.removeClass('ui-selecting');
+                                               selectee.selecting = false;
+                                               selectee.$element.addClass('ui-selected');
+                                               selectee.selected = true;
+                                       } else {
+                                               selectee.$element.removeClass('ui-selecting');
+                                               selectee.selecting = false;
+                                               if (selectee.startselected) {
+                                                       selectee.$element.addClass('ui-unselecting');
+                                                       selectee.unselecting = true;
+                                               }
+                                               // selectable UNSELECTING callback
+                                               self._trigger("unselecting", event, {
+                                                       unselecting: selectee.element
+                                               });
+                                       }
+                               }
+                               if (selectee.selected) {
+                                       if (!event.metaKey && !selectee.startselected) {
+                                               selectee.$element.removeClass('ui-selected');
+                                               selectee.selected = false;
+
+                                               selectee.$element.addClass('ui-unselecting');
+                                               selectee.unselecting = true;
+                                               // selectable UNSELECTING callback
+                                               self._trigger("unselecting", event, {
+                                                       unselecting: selectee.element
+                                               });
+                                       }
+                               }
+                       }
+               });
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+               var self = this;
+
+               this.dragged = false;
+
+               var options = this.options;
+
+               $('.ui-unselecting', this.element[0]).each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.$element.removeClass('ui-unselecting');
+                       selectee.unselecting = false;
+                       selectee.startselected = false;
+                       self._trigger("unselected", event, {
+                               unselected: selectee.element
+                       });
+               });
+               $('.ui-selecting', this.element[0]).each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
+                       selectee.selecting = false;
+                       selectee.selected = true;
+                       selectee.startselected = true;
+                       self._trigger("selected", event, {
+                               selected: selectee.element
+                       });
+               });
+               this._trigger("stop", event);
+
+               this.helper.remove();
+
+               return false;
+       }
+
+});
+
+$.extend($.ui.selectable, {
+       version: "1.8.12"
+});
+
+})(jQuery);
+/*
+ * jQuery UI Sortable 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Sortables
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.mouse.js
+ *     jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.sortable", $.ui.mouse, {
+       widgetEventPrefix: "sort",
+       options: {
+               appendTo: "parent",
+               axis: false,
+               connectWith: false,
+               containment: false,
+               cursor: 'auto',
+               cursorAt: false,
+               dropOnEmpty: true,
+               forcePlaceholderSize: false,
+               forceHelperSize: false,
+               grid: false,
+               handle: false,
+               helper: "original",
+               items: '> *',
+               opacity: false,
+               placeholder: false,
+               revert: false,
+               scroll: true,
+               scrollSensitivity: 20,
+               scrollSpeed: 20,
+               scope: "default",
+               tolerance: "intersect",
+               zIndex: 1000
+       },
+       _create: function() {
+
+               var o = this.options;
+               this.containerCache = {};
+               this.element.addClass("ui-sortable");
+
+               //Get the items
+               this.refresh();
+
+               //Let's determine if the items are being displayed horizontally
+               this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
+
+               //Let's determine the parent's offset
+               this.offset = this.element.offset();
+
+               //Initialize mouse events for interaction
+               this._mouseInit();
+
+       },
+
+       destroy: function() {
+               this.element
+                       .removeClass("ui-sortable ui-sortable-disabled")
+                       .removeData("sortable")
+                       .unbind(".sortable");
+               this._mouseDestroy();
+
+               for ( var i = this.items.length - 1; i >= 0; i-- )
+                       this.items[i].item.removeData("sortable-item");
+
+               return this;
+       },
+
+       _setOption: function(key, value){
+               if ( key === "disabled" ) {
+                       this.options[ key ] = value;
+       
+                       this.widget()
+                               [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
+               } else {
+                       // Don't call widget base _setOption for disable as it adds ui-state-disabled class
+                       $.Widget.prototype._setOption.apply(this, arguments);
+               }
+       },
+
+       _mouseCapture: function(event, overrideHandle) {
+
+               if (this.reverting) {
+                       return false;
+               }
+
+               if(this.options.disabled || this.options.type == 'static') return false;
+
+               //We have to refresh the items data once first
+               this._refreshItems(event);
+
+               //Find out if the clicked node (or one of its parents) is a actual item in this.items
+               var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
+                       if($.data(this, 'sortable-item') == self) {
+                               currentItem = $(this);
+                               return false;
+                       }
+               });
+               if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
+
+               if(!currentItem) return false;
+               if(this.options.handle && !overrideHandle) {
+                       var validHandle = false;
+
+                       $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
+                       if(!validHandle) return false;
+               }
+
+               this.currentItem = currentItem;
+               this._removeCurrentsFromItems();
+               return true;
+
+       },
+
+       _mouseStart: function(event, overrideHandle, noActivation) {
+
+               var o = this.options, self = this;
+               this.currentContainer = this;
+
+               //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
+               this.refreshPositions();
+
+               //Create and append the visible helper
+               this.helper = this._createHelper(event);
+
+               //Cache the helper size
+               this._cacheHelperProportions();
+
+               /*
+                * - Position generation -
+                * This block generates everything position related - it's the core of draggables.
+                */
+
+               //Cache the margins of the original element
+               this._cacheMargins();
+
+               //Get the next scrolling parent
+               this.scrollParent = this.helper.scrollParent();
+
+               //The element's absolute position on the page minus margins
+               this.offset = this.currentItem.offset();
+               this.offset = {
+                       top: this.offset.top - this.margins.top,
+                       left: this.offset.left - this.margins.left
+               };
+
+               // Only after we got the offset, we can change the helper's position to absolute
+               // TODO: Still need to figure out a way to make relative sorting possible
+               this.helper.css("position", "absolute");
+               this.cssPosition = this.helper.css("position");
+
+               $.extend(this.offset, {
+                       click: { //Where the click happened, relative to the element
+                               left: event.pageX - this.offset.left,
+                               top: event.pageY - this.offset.top
+                       },
+                       parent: this._getParentOffset(),
+                       relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+               });
+
+               //Generate the original position
+               this.originalPosition = this._generatePosition(event);
+               this.originalPageX = event.pageX;
+               this.originalPageY = event.pageY;
+
+               //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
+               (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+               //Cache the former DOM position
+               this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
+
+               //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
+               if(this.helper[0] != this.currentItem[0]) {
+                       this.currentItem.hide();
+               }
+
+               //Create the placeholder
+               this._createPlaceholder();
+
+               //Set a containment if given in the options
+               if(o.containment)
+                       this._setContainment();
+
+               if(o.cursor) { // cursor option
+                       if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
+                       $('body').css("cursor", o.cursor);
+               }
+
+               if(o.opacity) { // opacity option
+                       if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
+                       this.helper.css("opacity", o.opacity);
+               }
+
+               if(o.zIndex) { // zIndex option
+                       if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
+                       this.helper.css("zIndex", o.zIndex);
+               }
+
+               //Prepare scrolling
+               if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
+                       this.overflowOffset = this.scrollParent.offset();
+
+               //Call callbacks
+               this._trigger("start", event, this._uiHash());
+
+               //Recache the helper size
+               if(!this._preserveHelperProportions)
+                       this._cacheHelperProportions();
+
+
+               //Post 'activate' events to possible containers
+               if(!noActivation) {
+                        for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
+               }
+
+               //Prepare possible droppables
+               if($.ui.ddmanager)
+                       $.ui.ddmanager.current = this;
+
+               if ($.ui.ddmanager && !o.dropBehaviour)
+                       $.ui.ddmanager.prepareOffsets(this, event);
+
+               this.dragging = true;
+
+               this.helper.addClass("ui-sortable-helper");
+               this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+               return true;
+
+       },
+
+       _mouseDrag: function(event) {
+
+               //Compute the helpers position
+               this.position = this._generatePosition(event);
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               if (!this.lastPositionAbs) {
+                       this.lastPositionAbs = this.positionAbs;
+               }
+
+               //Do scrolling
+               if(this.options.scroll) {
+                       var o = this.options, scrolled = false;
+                       if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
+
+                               if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
+                                       this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
+                               else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
+                                       this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
+
+                               if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
+                                       this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
+                               else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
+                                       this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
+
+                       } else {
+
+                               if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
+                                       scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+                               else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
+                                       scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+
+                               if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+                               else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+
+                       }
+
+                       if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
+                               $.ui.ddmanager.prepareOffsets(this, event);
+               }
+
+               //Regenerate the absolute position used for position checks
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               //Set the helper position
+               if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
+               if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
+
+               //Rearrange
+               for (var i = this.items.length - 1; i >= 0; i--) {
+
+                       //Cache variables and intersection, continue if no intersection
+                       var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
+                       if (!intersection) continue;
+
+                       if(itemElement != this.currentItem[0] //cannot intersect with itself
+                               &&      this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
+                               &&      !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
+                               && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
+                               //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
+                       ) {
+
+                               this.direction = intersection == 1 ? "down" : "up";
+
+                               if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
+                                       this._rearrange(event, item);
+                               } else {
+                                       break;
+                               }
+
+                               this._trigger("change", event, this._uiHash());
+                               break;
+                       }
+               }
+
+               //Post events to containers
+               this._contactContainers(event);
+
+               //Interconnect with droppables
+               if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
+
+               //Call callbacks
+               this._trigger('sort', event, this._uiHash());
+
+               this.lastPositionAbs = this.positionAbs;
+               return false;
+
+       },
+
+       _mouseStop: function(event, noPropagation) {
+
+               if(!event) return;
+
+               //If we are using droppables, inform the manager about the drop
+               if ($.ui.ddmanager && !this.options.dropBehaviour)
+                       $.ui.ddmanager.drop(this, event);
+
+               if(this.options.revert) {
+                       var self = this;
+                       var cur = self.placeholder.offset();
+
+                       self.reverting = true;
+
+                       $(this.helper).animate({
+                               left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
+                               top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
+                       }, parseInt(this.options.revert, 10) || 500, function() {
+                               self._clear(event);
+                       });
+               } else {
+                       this._clear(event, noPropagation);
+               }
+
+               return false;
+
+       },
+
+       cancel: function() {
+
+               var self = this;
+
+               if(this.dragging) {
+
+                       this._mouseUp({ target: null });
+
+                       if(this.options.helper == "original")
+                               this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+                       else
+                               this.currentItem.show();
+
+                       //Post deactivating events to containers
+                       for (var i = this.containers.length - 1; i >= 0; i--){
+                               this.containers[i]._trigger("deactivate", null, self._uiHash(this));
+                               if(this.containers[i].containerCache.over) {
+                                       this.containers[i]._trigger("out", null, self._uiHash(this));
+                                       this.containers[i].containerCache.over = 0;
+                               }
+                       }
+
+               }
+
+               if (this.placeholder) {
+                       //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+                       if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+                       if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
+
+                       $.extend(this, {
+                               helper: null,
+                               dragging: false,
+                               reverting: false,
+                               _noFinalSort: null
+                       });
+
+                       if(this.domPosition.prev) {
+                               $(this.domPosition.prev).after(this.currentItem);
+                       } else {
+                               $(this.domPosition.parent).prepend(this.currentItem);
+                       }
+               }
+
+               return this;
+
+       },
+
+       serialize: function(o) {
+
+               var items = this._getItemsAsjQuery(o && o.connected);
+               var str = []; o = o || {};
+
+               $(items).each(function() {
+                       var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
+                       if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
+               });
+
+               if(!str.length && o.key) {
+                       str.push(o.key + '=');
+               }
+
+               return str.join('&');
+
+       },
+
+       toArray: function(o) {
+
+               var items = this._getItemsAsjQuery(o && o.connected);
+               var ret = []; o = o || {};
+
+               items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
+               return ret;
+
+       },
+
+       /* Be careful with the following core functions */
+       _intersectsWith: function(item) {
+
+               var x1 = this.positionAbs.left,
+                       x2 = x1 + this.helperProportions.width,
+                       y1 = this.positionAbs.top,
+                       y2 = y1 + this.helperProportions.height;
+
+               var l = item.left,
+                       r = l + item.width,
+                       t = item.top,
+                       b = t + item.height;
+
+               var dyClick = this.offset.click.top,
+                       dxClick = this.offset.click.left;
+
+               var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
+
+               if(        this.options.tolerance == "pointer"
+                       || this.options.forcePointerForContainers
+                       || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
+               ) {
+                       return isOverElement;
+               } else {
+
+                       return (l < x1 + (this.helperProportions.width / 2) // Right Half
+                               && x2 - (this.helperProportions.width / 2) < r // Left Half
+                               && t < y1 + (this.helperProportions.height / 2) // Bottom Half
+                               && y2 - (this.helperProportions.height / 2) < b ); // Top Half
+
+               }
+       },
+
+       _intersectsWithPointer: function(item) {
+
+               var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
+                       isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
+                       isOverElement = isOverElementHeight && isOverElementWidth,
+                       verticalDirection = this._getDragVerticalDirection(),
+                       horizontalDirection = this._getDragHorizontalDirection();
+
+               if (!isOverElement)
+                       return false;
+
+               return this.floating ?
+                       ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
+                       : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
+
+       },
+
+       _intersectsWithSides: function(item) {
+
+               var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
+                       isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
+                       verticalDirection = this._getDragVerticalDirection(),
+                       horizontalDirection = this._getDragHorizontalDirection();
+
+               if (this.floating && horizontalDirection) {
+                       return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
+               } else {
+                       return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
+               }
+
+       },
+
+       _getDragVerticalDirection: function() {
+               var delta = this.positionAbs.top - this.lastPositionAbs.top;
+               return delta != 0 && (delta > 0 ? "down" : "up");
+       },
+
+       _getDragHorizontalDirection: function() {
+               var delta = this.positionAbs.left - this.lastPositionAbs.left;
+               return delta != 0 && (delta > 0 ? "right" : "left");
+       },
+
+       refresh: function(event) {
+               this._refreshItems(event);
+               this.refreshPositions();
+               return this;
+       },
+
+       _connectWith: function() {
+               var options = this.options;
+               return options.connectWith.constructor == String
+                       ? [options.connectWith]
+                       : options.connectWith;
+       },
+       
+       _getItemsAsjQuery: function(connected) {
+
+               var self = this;
+               var items = [];
+               var queries = [];
+               var connectWith = this._connectWith();
+
+               if(connectWith && connected) {
+                       for (var i = connectWith.length - 1; i >= 0; i--){
+                               var cur = $(connectWith[i]);
+                               for (var j = cur.length - 1; j >= 0; j--){
+                                       var inst = $.data(cur[j], 'sortable');
+                                       if(inst && inst != this && !inst.options.disabled) {
+                                               queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
+                                       }
+                               };
+                       };
+               }
+
+               queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
+
+               for (var i = queries.length - 1; i >= 0; i--){
+                       queries[i][0].each(function() {
+                               items.push(this);
+                       });
+               };
+
+               return $(items);
+
+       },
+
+       _removeCurrentsFromItems: function() {
+
+               var list = this.currentItem.find(":data(sortable-item)");
+
+               for (var i=0; i < this.items.length; i++) {
+
+                       for (var j=0; j < list.length; j++) {
+                               if(list[j] == this.items[i].item[0])
+                                       this.items.splice(i,1);
+                       };
+
+               };
+
+       },
+
+       _refreshItems: function(event) {
+
+               this.items = [];
+               this.containers = [this];
+               var items = this.items;
+               var self = this;
+               var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
+               var connectWith = this._connectWith();
+
+               if(connectWith) {
+                       for (var i = connectWith.length - 1; i >= 0; i--){
+                               var cur = $(connectWith[i]);
+                               for (var j = cur.length - 1; j >= 0; j--){
+                                       var inst = $.data(cur[j], 'sortable');
+                                       if(inst && inst != this && !inst.options.disabled) {
+                                               queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
+                                               this.containers.push(inst);
+                                       }
+                               };
+                       };
+               }
+
+               for (var i = queries.length - 1; i >= 0; i--) {
+                       var targetData = queries[i][1];
+                       var _queries = queries[i][0];
+
+                       for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
+                               var item = $(_queries[j]);
+
+                               item.data('sortable-item', targetData); // Data for target checking (mouse manager)
+
+                               items.push({
+                                       item: item,
+                                       instance: targetData,
+                                       width: 0, height: 0,
+                                       left: 0, top: 0
+                               });
+                       };
+               };
+
+       },
+
+       refreshPositions: function(fast) {
+
+               //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
+               if(this.offsetParent && this.helper) {
+                       this.offset.parent = this._getParentOffset();
+               }
+
+               for (var i = this.items.length - 1; i >= 0; i--){
+                       var item = this.items[i];
+
+                       //We ignore calculating positions of all connected containers when we're not over them
+                       if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
+                               continue;
+
+                       var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
+
+                       if (!fast) {
+                               item.width = t.outerWidth();
+                               item.height = t.outerHeight();
+                       }
+
+                       var p = t.offset();
+                       item.left = p.left;
+                       item.top = p.top;
+               };
+
+               if(this.options.custom && this.options.custom.refreshContainers) {
+                       this.options.custom.refreshContainers.call(this);
+               } else {
+                       for (var i = this.containers.length - 1; i >= 0; i--){
+                               var p = this.containers[i].element.offset();
+                               this.containers[i].containerCache.left = p.left;
+                               this.containers[i].containerCache.top = p.top;
+                               this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
+                               this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
+                       };
+               }
+
+               return this;
+       },
+
+       _createPlaceholder: function(that) {
+
+               var self = that || this, o = self.options;
+
+               if(!o.placeholder || o.placeholder.constructor == String) {
+                       var className = o.placeholder;
+                       o.placeholder = {
+                               element: function() {
+
+                                       var el = $(document.createElement(self.currentItem[0].nodeName))
+                                               .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
+                                               .removeClass("ui-sortable-helper")[0];
+
+                                       if(!className)
+                                               el.style.visibility = "hidden";
+
+                                       return el;
+                               },
+                               update: function(container, p) {
+
+                                       // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
+                                       // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
+                                       if(className && !o.forcePlaceholderSize) return;
+
+                                       //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
+                                       if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
+                                       if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
+                               }
+                       };
+               }
+
+               //Create the placeholder
+               self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
+
+               //Append it after the actual current item
+               self.currentItem.after(self.placeholder);
+
+               //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
+               o.placeholder.update(self, self.placeholder);
+
+       },
+
+       _contactContainers: function(event) {
+               
+               // get innermost container that intersects with item 
+               var innermostContainer = null, innermostIndex = null;           
+               
+               
+               for (var i = this.containers.length - 1; i >= 0; i--){
+
+                       // never consider a container that's located within the item itself 
+                       if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
+                               continue;
+
+                       if(this._intersectsWith(this.containers[i].containerCache)) {
+
+                               // if we've already found a container and it's more "inner" than this, then continue 
+                               if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
+                                       continue;
+
+                               innermostContainer = this.containers[i]; 
+                               innermostIndex = i;
+                                       
+                       } else {
+                               // container doesn't intersect. trigger "out" event if necessary 
+                               if(this.containers[i].containerCache.over) {
+                                       this.containers[i]._trigger("out", event, this._uiHash(this));
+                                       this.containers[i].containerCache.over = 0;
+                               }
+                       }
+
+               }
+               
+               // if no intersecting containers found, return 
+               if(!innermostContainer) return; 
+
+               // move the item into the container if it's not there already
+               if(this.containers.length === 1) {
+                       this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+                       this.containers[innermostIndex].containerCache.over = 1;
+               } else if(this.currentContainer != this.containers[innermostIndex]) { 
+
+                       //When entering a new container, we will find the item with the least distance and append our item near it 
+                       var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; 
+                       for (var j = this.items.length - 1; j >= 0; j--) { 
+                               if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 
+                               var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; 
+                               if(Math.abs(cur - base) < dist) { 
+                                       dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 
+                               } 
+                       } 
+
+                       if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 
+                               return; 
+
+                       this.currentContainer = this.containers[innermostIndex]; 
+                       itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 
+                       this._trigger("change", event, this._uiHash()); 
+                       this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 
+
+                       //Update the placeholder 
+                       this.options.placeholder.update(this.currentContainer, this.placeholder); 
+               
+                       this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 
+                       this.containers[innermostIndex].containerCache.over = 1;
+               } 
+       
+               
+       },
+
+       _createHelper: function(event) {
+
+               var o = this.options;
+               var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
+
+               if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
+                       $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
+
+               if(helper[0] == this.currentItem[0])
+                       this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
+
+               if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
+               if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
+
+               return helper;
+
+       },
+
+       _adjustOffsetFromHelper: function(obj) {
+               if (typeof obj == 'string') {
+                       obj = obj.split(' ');
+               }
+               if ($.isArray(obj)) {
+                       obj = {left: +obj[0], top: +obj[1] || 0};
+               }
+               if ('left' in obj) {
+                       this.offset.click.left = obj.left + this.margins.left;
+               }
+               if ('right' in obj) {
+                       this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+               }
+               if ('top' in obj) {
+                       this.offset.click.top = obj.top + this.margins.top;
+               }
+               if ('bottom' in obj) {
+                       this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+               }
+       },
+
+       _getParentOffset: function() {
+
+
+               //Get the offsetParent and cache its position
+               this.offsetParent = this.helper.offsetParent();
+               var po = this.offsetParent.offset();
+
+               // This is a special case where we need to modify a offset calculated on start, since the following happened:
+               // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+               // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+               //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+               if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
+                       po.left += this.scrollParent.scrollLeft();
+                       po.top += this.scrollParent.scrollTop();
+               }
+
+               if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
+               || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
+                       po = { top: 0, left: 0 };
+
+               return {
+                       top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+                       left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+               };
+
+       },
+
+       _getRelativeOffset: function() {
+
+               if(this.cssPosition == "relative") {
+                       var p = this.currentItem.position();
+                       return {
+                               top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+                               left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+                       };
+               } else {
+                       return { top: 0, left: 0 };
+               }
+
+       },
+
+       _cacheMargins: function() {
+               this.margins = {
+                       left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
+                       top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
+               };
+       },
+
+       _cacheHelperProportions: function() {
+               this.helperProportions = {
+                       width: this.helper.outerWidth(),
+                       height: this.helper.outerHeight()
+               };
+       },
+
+       _setContainment: function() {
+
+               var o = this.options;
+               if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
+               if(o.containment == 'document' || o.containment == 'window') this.containment = [
+                       0 - this.offset.relative.left - this.offset.parent.left,
+                       0 - this.offset.relative.top - this.offset.parent.top,
+                       $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
+                       ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+               ];
+
+               if(!(/^(document|window|parent)$/).test(o.containment)) {
+                       var ce = $(o.containment)[0];
+                       var co = $(o.containment).offset();
+                       var over = ($(ce).css("overflow") != 'hidden');
+
+                       this.containment = [
+                               co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
+                               co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
+                               co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
+                               co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
+                       ];
+               }
+
+       },
+
+       _convertPositionTo: function(d, pos) {
+
+               if(!pos) pos = this.position;
+               var mod = d == "absolute" ? 1 : -1;
+               var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+               return {
+                       top: (
+                               pos.top                                                                                                                                 // The absolute mouse position
+                               + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
+                               + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
+                               - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+                       ),
+                       left: (
+                               pos.left                                                                                                                                // The absolute mouse position
+                               + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
+                               + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
+                               - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+                       )
+               };
+
+       },
+
+       _generatePosition: function(event) {
+
+               var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+               // This is another very weird special case that only happens for relative elements:
+               // 1. If the css position is relative
+               // 2. and the scroll parent is the document or similar to the offset parent
+               // we have to refresh the relative offset during the scroll so there are no jumps
+               if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
+                       this.offset.relative = this._getRelativeOffset();
+               }
+
+               var pageX = event.pageX;
+               var pageY = event.pageY;
+
+               /*
+                * - Position constraining -
+                * Constrain the position to a mix of grid, containment.
+                */
+
+               if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+
+                       if(this.containment) {
+                               if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
+                               if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
+                               if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
+                               if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
+                       }
+
+                       if(o.grid) {
+                               var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
+                               pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+                               var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
+                               pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+                       }
+
+               }
+
+               return {
+                       top: (
+                               pageY                                                                                                                           // The absolute mouse position
+                               - this.offset.click.top                                                                                                 // Click offset (relative to the element)
+                               - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
+                               - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
+                               + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+                       ),
+                       left: (
+                               pageX                                                                                                                           // The absolute mouse position
+                               - this.offset.click.left                                                                                                // Click offset (relative to the element)
+                               - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
+                               - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
+                               + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+                       )
+               };
+
+       },
+
+       _rearrange: function(event, i, a, hardRefresh) {
+
+               a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
+
+               //Various things done here to improve the performance:
+               // 1. we create a setTimeout, that calls refreshPositions
+               // 2. on the instance, we have a counter variable, that get's higher after every append
+               // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
+               // 4. this lets only the last addition to the timeout stack through
+               this.counter = this.counter ? ++this.counter : 1;
+               var self = this, counter = this.counter;
+
+               window.setTimeout(function() {
+                       if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
+               },0);
+
+       },
+
+       _clear: function(event, noPropagation) {
+
+               this.reverting = false;
+               // We delay all events that have to be triggered to after the point where the placeholder has been removed and
+               // everything else normalized again
+               var delayedTriggers = [], self = this;
+
+               // We first have to update the dom position of the actual currentItem
+               // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
+               if(!this._noFinalSort && this.currentItem[0].parentNode) this.placeholder.before(this.currentItem);
+               this._noFinalSort = null;
+
+               if(this.helper[0] == this.currentItem[0]) {
+                       for(var i in this._storedCSS) {
+                               if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
+                       }
+                       this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+               } else {
+                       this.currentItem.show();
+               }
+
+               if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
+               if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
+               if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
+                       if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
+                       for (var i = this.containers.length - 1; i >= 0; i--){
+                               if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
+                                       delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
+                                       delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.containers[i]));
+                               }
+                       };
+               };
+
+               //Post events to containers
+               for (var i = this.containers.length - 1; i >= 0; i--){
+                       if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
+                       if(this.containers[i].containerCache.over) {
+                               delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
+                               this.containers[i].containerCache.over = 0;
+                       }
+               }
+
+               //Do what was originally in plugins
+               if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
+               if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
+               if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
+
+               this.dragging = false;
+               if(this.cancelHelperRemoval) {
+                       if(!noPropagation) {
+                               this._trigger("beforeStop", event, this._uiHash());
+                               for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
+                               this._trigger("stop", event, this._uiHash());
+                       }
+                       return false;
+               }
+
+               if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
+
+               //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+               this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+
+               if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
+
+               if(!noPropagation) {
+                       for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
+                       this._trigger("stop", event, this._uiHash());
+               }
+
+               this.fromOutside = false;
+               return true;
+
+       },
+
+       _trigger: function() {
+               if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
+                       this.cancel();
+               }
+       },
+
+       _uiHash: function(inst) {
+               var self = inst || this;
+               return {
+                       helper: self.helper,
+                       placeholder: self.placeholder || $([]),
+                       position: self.position,
+                       originalPosition: self.originalPosition,
+                       offset: self.positionAbs,
+                       item: self.currentItem,
+                       sender: inst ? inst.element : null
+               };
+       }
+
+});
+
+$.extend($.ui.sortable, {
+       version: "1.8.12"
+});
+
+})(jQuery);
+/*
+ * jQuery UI Effects 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/
+ */
+;jQuery.effects || (function($, undefined) {
+
+$.effects = {};
+
+
+
+/******************************************************************************/
+/****************************** COLOR ANIMATIONS ******************************/
+/******************************************************************************/
+
+// override the animation for color styles
+$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
+       'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
+function(i, attr) {
+       $.fx.step[attr] = function(fx) {
+               if (!fx.colorInit) {
+                       fx.start = getColor(fx.elem, attr);
+                       fx.end = getRGB(fx.end);
+                       fx.colorInit = true;
+               }
+
+               fx.elem.style[attr] = 'rgb(' +
+                       Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
+                       Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
+                       Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
+       };
+});
+
+// Color Conversion functions from highlightFade
+// By Blair Mitchelmore
+// http://jquery.offput.ca/highlightFade/
+
+// Parse strings looking for color tuples [255,255,255]
+function getRGB(color) {
+               var result;
+
+               // Check if we're already dealing with an array of colors
+               if ( color && color.constructor == Array && color.length == 3 )
+                               return color;
+
+               // Look for rgb(num,num,num)
+               if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
+                               return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
+
+               // Look for rgb(num%,num%,num%)
+               if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
+                               return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
+
+               // Look for #a0b1c2
+               if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
+                               return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
+
+               // Look for #fff
+               if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
+                               return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
+
+               // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
+               if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
+                               return colors['transparent'];
+
+               // Otherwise, we're most likely dealing with a named color
+               return colors[$.trim(color).toLowerCase()];
+}
+
+function getColor(elem, attr) {
+               var color;
+
+               do {
+                               color = $.curCSS(elem, attr);
+
+                               // Keep going until we find an element that has color, or we hit the body
+                               if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
+                                               break;
+
+                               attr = "backgroundColor";
+               } while ( elem = elem.parentNode );
+
+               return getRGB(color);
+};
+
+// Some named colors to work with
+// From Interface by Stefan Petre
+// http://interface.eyecon.ro/
+
+var colors = {
+       aqua:[0,255,255],
+       azure:[240,255,255],
+       beige:[245,245,220],
+       black:[0,0,0],
+       blue:[0,0,255],
+       brown:[165,42,42],
+       cyan:[0,255,255],
+       darkblue:[0,0,139],
+       darkcyan:[0,139,139],
+       darkgrey:[169,169,169],
+       darkgreen:[0,100,0],
+       darkkhaki:[189,183,107],
+       darkmagenta:[139,0,139],
+       darkolivegreen:[85,107,47],
+       darkorange:[255,140,0],
+       darkorchid:[153,50,204],
+       darkred:[139,0,0],
+       darksalmon:[233,150,122],
+       darkviolet:[148,0,211],
+       fuchsia:[255,0,255],
+       gold:[255,215,0],
+       green:[0,128,0],
+       indigo:[75,0,130],
+       khaki:[240,230,140],
+       lightblue:[173,216,230],
+       lightcyan:[224,255,255],
+       lightgreen:[144,238,144],
+       lightgrey:[211,211,211],
+       lightpink:[255,182,193],
+       lightyellow:[255,255,224],
+       lime:[0,255,0],
+       magenta:[255,0,255],
+       maroon:[128,0,0],
+       navy:[0,0,128],
+       olive:[128,128,0],
+       orange:[255,165,0],
+       pink:[255,192,203],
+       purple:[128,0,128],
+       violet:[128,0,128],
+       red:[255,0,0],
+       silver:[192,192,192],
+       white:[255,255,255],
+       yellow:[255,255,0],
+       transparent: [255,255,255]
+};
+
+
+
+/******************************************************************************/
+/****************************** CLASS ANIMATIONS ******************************/
+/******************************************************************************/
+
+var classAnimationActions = ['add', 'remove', 'toggle'],
+       shorthandStyles = {
+               border: 1,
+               borderBottom: 1,
+               borderColor: 1,
+               borderLeft: 1,
+               borderRight: 1,
+               borderTop: 1,
+               borderWidth: 1,
+               margin: 1,
+               padding: 1
+       };
+
+function getElementStyles() {
+       var style = document.defaultView
+                       ? document.defaultView.getComputedStyle(this, null)
+                       : this.currentStyle,
+               newStyle = {},
+               key,
+               camelCase;
+
+       // webkit enumerates style porperties
+       if (style && style.length && style[0] && style[style[0]]) {
+               var len = style.length;
+               while (len--) {
+                       key = style[len];
+                       if (typeof style[key] == 'string') {
+                               camelCase = key.replace(/\-(\w)/g, function(all, letter){
+                                       return letter.toUpperCase();
+                               });
+                               newStyle[camelCase] = style[key];
+                       }
+               }
+       } else {
+               for (key in style) {
+                       if (typeof style[key] === 'string') {
+                               newStyle[key] = style[key];
+                       }
+               }
+       }
+       
+       return newStyle;
+}
+
+function filterStyles(styles) {
+       var name, value;
+       for (name in styles) {
+               value = styles[name];
+               if (
+                       // ignore null and undefined values
+                       value == null ||
+                       // ignore functions (when does this occur?)
+                       $.isFunction(value) ||
+                       // shorthand styles that need to be expanded
+                       name in shorthandStyles ||
+                       // ignore scrollbars (break in IE)
+                       (/scrollbar/).test(name) ||
+
+                       // only colors or values that can be converted to numbers
+                       (!(/color/i).test(name) && isNaN(parseFloat(value)))
+               ) {
+                       delete styles[name];
+               }
+       }
+       
+       return styles;
+}
+
+function styleDifference(oldStyle, newStyle) {
+       var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
+               name;
+
+       for (name in newStyle) {
+               if (oldStyle[name] != newStyle[name]) {
+                       diff[name] = newStyle[name];
+               }
+       }
+
+       return diff;
+}
+
+$.effects.animateClass = function(value, duration, easing, callback) {
+       if ($.isFunction(easing)) {
+               callback = easing;
+               easing = null;
+       }
+
+       return this.queue('fx', function() {
+               var that = $(this),
+                       originalStyleAttr = that.attr('style') || ' ',
+                       originalStyle = filterStyles(getElementStyles.call(this)),
+                       newStyle,
+                       className = that.attr('className');
+
+               $.each(classAnimationActions, function(i, action) {
+                       if (value[action]) {
+                               that[action + 'Class'](value[action]);
+                       }
+               });
+               newStyle = filterStyles(getElementStyles.call(this));
+               that.attr('className', className);
+
+               that.animate(styleDifference(originalStyle, newStyle), duration, easing, function() {
+                       $.each(classAnimationActions, function(i, action) {
+                               if (value[action]) { that[action + 'Class'](value[action]); }
+                       });
+                       // work around bug in IE by clearing the cssText before setting it
+                       if (typeof that.attr('style') == 'object') {
+                               that.attr('style').cssText = '';
+                               that.attr('style').cssText = originalStyleAttr;
+                       } else {
+                               that.attr('style', originalStyleAttr);
+                       }
+                       if (callback) { callback.apply(this, arguments); }
+               });
+
+               // $.animate adds a function to the end of the queue
+               // but we want it at the front
+               var queue = $.queue(this),
+                       anim = queue.splice(queue.length - 1, 1)[0];
+               queue.splice(1, 0, anim);
+               $.dequeue(this);
+       });
+};
+
+$.fn.extend({
+       _addClass: $.fn.addClass,
+       addClass: function(classNames, speed, easing, callback) {
+               return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
+       },
+
+       _removeClass: $.fn.removeClass,
+       removeClass: function(classNames,speed,easing,callback) {
+               return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
+       },
+
+       _toggleClass: $.fn.toggleClass,
+       toggleClass: function(classNames, force, speed, easing, callback) {
+               if ( typeof force == "boolean" || force === undefined ) {
+                       if ( !speed ) {
+                               // without speed parameter;
+                               return this._toggleClass(classNames, force);
+                       } else {
+                               return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
+                       }
+               } else {
+                       // without switch parameter;
+                       return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
+               }
+       },
+
+       switchClass: function(remove,add,speed,easing,callback) {
+               return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
+       }
+});
+
+
+
+/******************************************************************************/
+/*********************************** EFFECTS **********************************/
+/******************************************************************************/
+
+$.extend($.effects, {
+       version: "1.8.12",
+
+       // Saves a set of properties in a data storage
+       save: function(element, set) {
+               for(var i=0; i < set.length; i++) {
+                       if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
+               }
+       },
+
+       // Restores a set of previously saved properties from a data storage
+       restore: function(element, set) {
+               for(var i=0; i < set.length; i++) {
+                       if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
+               }
+       },
+
+       setMode: function(el, mode) {
+               if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
+               return mode;
+       },
+
+       getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
+               // this should be a little more flexible in the future to handle a string & hash
+               var y, x;
+               switch (origin[0]) {
+                       case 'top': y = 0; break;
+                       case 'middle': y = 0.5; break;
+                       case 'bottom': y = 1; break;
+                       default: y = origin[0] / original.height;
+               };
+               switch (origin[1]) {
+                       case 'left': x = 0; break;
+                       case 'center': x = 0.5; break;
+                       case 'right': x = 1; break;
+                       default: x = origin[1] / original.width;
+               };
+               return {x: x, y: y};
+       },
+
+       // Wraps the element around a wrapper that copies position properties
+       createWrapper: function(element) {
+
+               // if the element is already wrapped, return it
+               if (element.parent().is('.ui-effects-wrapper')) {
+                       return element.parent();
+               }
+
+               // wrap the element
+               var props = {
+                               width: element.outerWidth(true),
+                               height: element.outerHeight(true),
+                               'float': element.css('float')
+                       },
+                       wrapper = $('<div></div>')
+                               .addClass('ui-effects-wrapper')
+                               .css({
+                                       fontSize: '100%',
+                                       background: 'transparent',
+                                       border: 'none',
+                                       margin: 0,
+                                       padding: 0
+                               });
+
+               element.wrap(wrapper);
+               wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
+
+               // transfer positioning properties to the wrapper
+               if (element.css('position') == 'static') {
+                       wrapper.css({ position: 'relative' });
+                       element.css({ position: 'relative' });
+               } else {
+                       $.extend(props, {
+                               position: element.css('position'),
+                               zIndex: element.css('z-index')
+                       });
+                       $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
+                               props[pos] = element.css(pos);
+                               if (isNaN(parseInt(props[pos], 10))) {
+                                       props[pos] = 'auto';
+                               }
+                       });
+                       element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
+               }
+
+               return wrapper.css(props).show();
+       },
+
+       removeWrapper: function(element) {
+               if (element.parent().is('.ui-effects-wrapper'))
+                       return element.parent().replaceWith(element);
+               return element;
+       },
+
+       setTransition: function(element, list, factor, value) {
+               value = value || {};
+               $.each(list, function(i, x){
+                       unit = element.cssUnit(x);
+                       if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
+               });
+               return value;
+       }
+});
+
+
+function _normalizeArguments(effect, options, speed, callback) {
+       // shift params for method overloading
+       if (typeof effect == 'object') {
+               callback = options;
+               speed = null;
+               options = effect;
+               effect = options.effect;
+       }
+       if ($.isFunction(options)) {
+               callback = options;
+               speed = null;
+               options = {};
+       }
+        if (typeof options == 'number' || $.fx.speeds[options]) {
+               callback = speed;
+               speed = options;
+               options = {};
+       }
+       if ($.isFunction(speed)) {
+               callback = speed;
+               speed = null;
+       }
+
+       options = options || {};
+
+       speed = speed || options.duration;
+       speed = $.fx.off ? 0 : typeof speed == 'number'
+               ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
+
+       callback = callback || options.complete;
+
+       return [effect, options, speed, callback];
+}
+
+function standardSpeed( speed ) {
+       // valid standard speeds
+       if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
+               return true;
+       }
+       
+       // invalid strings - treat as "normal" speed
+       if ( typeof speed === "string" && !$.effects[ speed ] ) {
+               return true;
+       }
+       
+       return false;
+}
+
+$.fn.extend({
+       effect: function(effect, options, speed, callback) {
+               var args = _normalizeArguments.apply(this, arguments),
+                       // TODO: make effects take actual parameters instead of a hash
+                       args2 = {
+                               options: args[1],
+                               duration: args[2],
+                               callback: args[3]
+                       },
+                       mode = args2.options.mode,
+                       effectMethod = $.effects[effect];
+               
+               if ( $.fx.off || !effectMethod ) {
+                       // delegate to the original method (e.g., .show()) if possible
+                       if ( mode ) {
+                               return this[ mode ]( args2.duration, args2.callback );
+                       } else {
+                               return this.each(function() {
+                                       if ( args2.callback ) {
+                                               args2.callback.call( this );
+                                       }
+                               });
+                       }
+               }
+               
+               return effectMethod.call(this, args2);
+       },
+
+       _show: $.fn.show,
+       show: function(speed) {
+               if ( standardSpeed( speed ) ) {
+                       return this._show.apply(this, arguments);
+               } else {
+                       var args = _normalizeArguments.apply(this, arguments);
+                       args[1].mode = 'show';
+                       return this.effect.apply(this, args);
+               }
+       },
+
+       _hide: $.fn.hide,
+       hide: function(speed) {
+               if ( standardSpeed( speed ) ) {
+                       return this._hide.apply(this, arguments);
+               } else {
+                       var args = _normalizeArguments.apply(this, arguments);
+                       args[1].mode = 'hide';
+                       return this.effect.apply(this, args);
+               }
+       },
+
+       // jQuery core overloads toggle and creates _toggle
+       __toggle: $.fn.toggle,
+       toggle: function(speed) {
+               if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
+                       return this.__toggle.apply(this, arguments);
+               } else {
+                       var args = _normalizeArguments.apply(this, arguments);
+                       args[1].mode = 'toggle';
+                       return this.effect.apply(this, args);
+               }
+       },
+
+       // helper functions
+       cssUnit: function(key) {
+               var style = this.css(key), val = [];
+               $.each( ['em','px','%','pt'], function(i, unit){
+                       if(style.indexOf(unit) > 0)
+                               val = [parseFloat(style), unit];
+               });
+               return val;
+       }
+});
+
+
+
+/******************************************************************************/
+/*********************************** EASING ***********************************/
+/******************************************************************************/
+
+/*
+ * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
+ *
+ * Uses the built in easing capabilities added In jQuery 1.1
+ * to offer multiple easing options
+ *
+ * TERMS OF USE - jQuery Easing
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright 2008 George McGinley Smith
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+// t: current time, b: begInnIng value, c: change In value, d: duration
+$.easing.jswing = $.easing.swing;
+
+$.extend($.easing,
+{
+       def: 'easeOutQuad',
+       swing: function (x, t, b, c, d) {
+               //alert($.easing.default);
+               return $.easing[$.easing.def](x, t, b, c, d);
+       },
+       easeInQuad: function (x, t, b, c, d) {
+               return c*(t/=d)*t + b;
+       },
+       easeOutQuad: function (x, t, b, c, d) {
+               return -c *(t/=d)*(t-2) + b;
+       },
+       easeInOutQuad: function (x, t, b, c, d) {
+               if ((t/=d/2) < 1) return c/2*t*t + b;
+               return -c/2 * ((--t)*(t-2) - 1) + b;
+       },
+       easeInCubic: function (x, t, b, c, d) {
+               return c*(t/=d)*t*t + b;
+       },
+       easeOutCubic: function (x, t, b, c, d) {
+               return c*((t=t/d-1)*t*t + 1) + b;
+       },
+       easeInOutCubic: function (x, t, b, c, d) {
+               if ((t/=d/2) < 1) return c/2*t*t*t + b;
+               return c/2*((t-=2)*t*t + 2) + b;
+       },
+       easeInQuart: function (x, t, b, c, d) {
+               return c*(t/=d)*t*t*t + b;
+       },
+       easeOutQuart: function (x, t, b, c, d) {
+               return -c * ((t=t/d-1)*t*t*t - 1) + b;
+       },
+       easeInOutQuart: function (x, t, b, c, d) {
+               if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
+               return -c/2 * ((t-=2)*t*t*t - 2) + b;
+       },
+       easeInQuint: function (x, t, b, c, d) {
+               return c*(t/=d)*t*t*t*t + b;
+       },
+       easeOutQuint: function (x, t, b, c, d) {
+               return c*((t=t/d-1)*t*t*t*t + 1) + b;
+       },
+       easeInOutQuint: function (x, t, b, c, d) {
+               if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
+               return c/2*((t-=2)*t*t*t*t + 2) + b;
+       },
+       easeInSine: function (x, t, b, c, d) {
+               return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
+       },
+       easeOutSine: function (x, t, b, c, d) {
+               return c * Math.sin(t/d * (Math.PI/2)) + b;
+       },
+       easeInOutSine: function (x, t, b, c, d) {
+               return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
+       },
+       easeInExpo: function (x, t, b, c, d) {
+               return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
+       },
+       easeOutExpo: function (x, t, b, c, d) {
+               return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
+       },
+       easeInOutExpo: function (x, t, b, c, d) {
+               if (t==0) return b;
+               if (t==d) return b+c;
+               if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
+               return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
+       },
+       easeInCirc: function (x, t, b, c, d) {
+               return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
+       },
+       easeOutCirc: function (x, t, b, c, d) {
+               return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
+       },
+       easeInOutCirc: function (x, t, b, c, d) {
+               if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
+               return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
+       },
+       easeInElastic: function (x, t, b, c, d) {
+               var s=1.70158;var p=0;var a=c;
+               if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
+               if (a < Math.abs(c)) { a=c; var s=p/4; }
+               else var s = p/(2*Math.PI) * Math.asin (c/a);
+               return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+       },
+       easeOutElastic: function (x, t, b, c, d) {
+               var s=1.70158;var p=0;var a=c;
+               if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
+               if (a < Math.abs(c)) { a=c; var s=p/4; }
+               else var s = p/(2*Math.PI) * Math.asin (c/a);
+               return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
+       },
+       easeInOutElastic: function (x, t, b, c, d) {
+               var s=1.70158;var p=0;var a=c;
+               if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
+               if (a < Math.abs(c)) { a=c; var s=p/4; }
+               else var s = p/(2*Math.PI) * Math.asin (c/a);
+               if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+               return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
+       },
+       easeInBack: function (x, t, b, c, d, s) {
+               if (s == undefined) s = 1.70158;
+               return c*(t/=d)*t*((s+1)*t - s) + b;
+       },
+       easeOutBack: function (x, t, b, c, d, s) {
+               if (s == undefined) s = 1.70158;
+               return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
+       },
+       easeInOutBack: function (x, t, b, c, d, s) {
+               if (s == undefined) s = 1.70158;
+               if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
+               return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
+       },
+       easeInBounce: function (x, t, b, c, d) {
+               return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
+       },
+       easeOutBounce: function (x, t, b, c, d) {
+               if ((t/=d) < (1/2.75)) {
+                       return c*(7.5625*t*t) + b;
+               } else if (t < (2/2.75)) {
+                       return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
+               } else if (t < (2.5/2.75)) {
+                       return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
+               } else {
+                       return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
+               }
+       },
+       easeInOutBounce: function (x, t, b, c, d) {
+               if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
+               return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
+       }
+});
+
+/*
+ *
+ * TERMS OF USE - EASING EQUATIONS
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright 2001 Robert Penner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+})(jQuery);
+/*
+ * jQuery UI Effects Blind 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Blind
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.blind = function(o) {
+
+       return this.queue(function() {
+
+               // Create element
+               var el = $(this), props = ['position','top','bottom','left','right'];
+
+               // Set options
+               var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+               var direction = o.options.direction || 'vertical'; // Default direction
+
+               // Adjust
+               $.effects.save(el, props); el.show(); // Save & Show
+               var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+               var ref = (direction == 'vertical') ? 'height' : 'width';
+               var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
+               if(mode == 'show') wrapper.css(ref, 0); // Shift
+
+               // Animation
+               var animation = {};
+               animation[ref] = mode == 'show' ? distance : 0;
+
+               // Animate
+               wrapper.animate(animation, o.duration, o.options.easing, function() {
+                       if(mode == 'hide') el.hide(); // Hide
+                       $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+                       if(o.callback) o.callback.apply(el[0], arguments); // Callback
+                       el.dequeue();
+               });
+
+       });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Bounce 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Bounce
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.bounce = function(o) {
+
+       return this.queue(function() {
+
+               // Create element
+               var el = $(this), props = ['position','top','bottom','left','right'];
+
+               // Set options
+               var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+               var direction = o.options.direction || 'up'; // Default direction
+               var distance = o.options.distance || 20; // Default distance
+               var times = o.options.times || 5; // Default # of times
+               var speed = o.duration || 250; // Default speed per bounce
+               if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
+
+               // Adjust
+               $.effects.save(el, props); el.show(); // Save & Show
+               $.effects.createWrapper(el); // Create Wrapper
+               var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+               var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+               var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
+               if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
+               if (mode == 'hide') distance = distance / (times * 2);
+               if (mode != 'hide') times--;
+
+               // Animate
+               if (mode == 'show') { // Show Bounce
+                       var animation = {opacity: 1};
+                       animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+                       el.animate(animation, speed / 2, o.options.easing);
+                       distance = distance / 2;
+                       times--;
+               };
+               for (var i = 0; i < times; i++) { // Bounces
+                       var animation1 = {}, animation2 = {};
+                       animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+                       animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+                       el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
+                       distance = (mode == 'hide') ? distance * 2 : distance / 2;
+               };
+               if (mode == 'hide') { // Last Bounce
+                       var animation = {opacity: 0};
+                       animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
+                       el.animate(animation, speed / 2, o.options.easing, function(){
+                               el.hide(); // Hide
+                               $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+                               if(o.callback) o.callback.apply(this, arguments); // Callback
+                       });
+               } else {
+                       var animation1 = {}, animation2 = {};
+                       animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+                       animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+                       el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
+                               $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+                               if(o.callback) o.callback.apply(this, arguments); // Callback
+                       });
+               };
+               el.queue('fx', function() { el.dequeue(); });
+               el.dequeue();
+       });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Clip 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Clip
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.clip = function(o) {
+
+       return this.queue(function() {
+
+               // Create element
+               var el = $(this), props = ['position','top','bottom','left','right','height','width'];
+
+               // Set options
+               var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+               var direction = o.options.direction || 'vertical'; // Default direction
+
+               // Adjust
+               $.effects.save(el, props); el.show(); // Save & Show
+               var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+               var animate = el[0].tagName == 'IMG' ? wrapper : el;
+               var ref = {
+                       size: (direction == 'vertical') ? 'height' : 'width',
+                       position: (direction == 'vertical') ? 'top' : 'left'
+               };
+               var distance = (direction == 'vertical') ? animate.height() : animate.width();
+               if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
+
+               // Animation
+               var animation = {};
+               animation[ref.size] = mode == 'show' ? distance : 0;
+               animation[ref.position] = mode == 'show' ? 0 : distance / 2;
+
+               // Animate
+               animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+                       if(mode == 'hide') el.hide(); // Hide
+                       $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+                       if(o.callback) o.callback.apply(el[0], arguments); // Callback
+                       el.dequeue();
+               }});
+
+       });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Drop 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Drop
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.drop = function(o) {
+
+       return this.queue(function() {
+
+               // Create element
+               var el = $(this), props = ['position','top','bottom','left','right','opacity'];
+
+               // Set options
+               var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+               var direction = o.options.direction || 'left'; // Default Direction
+
+               // Adjust
+               $.effects.save(el, props); el.show(); // Save & Show
+               $.effects.createWrapper(el); // Create Wrapper
+               var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+               var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+               var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
+               if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
+
+               // Animation
+               var animation = {opacity: mode == 'show' ? 1 : 0};
+               animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
+
+               // Animate
+               el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+                       if(mode == 'hide') el.hide(); // Hide
+                       $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+                       if(o.callback) o.callback.apply(this, arguments); // Callback
+                       el.dequeue();
+               }});
+
+       });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Explode 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Explode
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.explode = function(o) {
+
+       return this.queue(function() {
+
+       var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
+       var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
+
+       o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
+       var el = $(this).show().css('visibility', 'hidden');
+       var offset = el.offset();
+
+       //Substract the margins - not fixing the problem yet.
+       offset.top -= parseInt(el.css("marginTop"),10) || 0;
+       offset.left -= parseInt(el.css("marginLeft"),10) || 0;
+
+       var width = el.outerWidth(true);
+       var height = el.outerHeight(true);
+
+       for(var i=0;i<rows;i++) { // =
+               for(var j=0;j<cells;j++) { // ||
+                       el
+                               .clone()
+                               .appendTo('body')
+                               .wrap('<div></div>')
+                               .css({
+                                       position: 'absolute',
+                                       visibility: 'visible',
+                                       left: -j*(width/cells),
+                                       top: -i*(height/rows)
+                               })
+                               .parent()
+                               .addClass('ui-effects-explode')
+                               .css({
+                                       position: 'absolute',
+                                       overflow: 'hidden',
+                                       width: width/cells,
+                                       height: height/rows,
+                                       left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
+                                       top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
+                                       opacity: o.options.mode == 'show' ? 0 : 1
+                               }).animate({
+                                       left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
+                                       top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
+                                       opacity: o.options.mode == 'show' ? 1 : 0
+                               }, o.duration || 500);
+               }
+       }
+
+       // Set a timeout, to call the callback approx. when the other animations have finished
+       setTimeout(function() {
+
+               o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
+                               if(o.callback) o.callback.apply(el[0]); // Callback
+                               el.dequeue();
+
+                               $('div.ui-effects-explode').remove();
+
+       }, o.duration || 500);
+
+
+       });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Fade 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Fade
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.fade = function(o) {
+       return this.queue(function() {
+               var elem = $(this),
+                       mode = $.effects.setMode(elem, o.options.mode || 'hide');
+
+               elem.animate({ opacity: mode }, {
+                       queue: false,
+                       duration: o.duration,
+                       easing: o.options.easing,
+                       complete: function() {
+                               (o.callback && o.callback.apply(this, arguments));
+                               elem.dequeue();
+                       }
+               });
+       });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Fold 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Fold
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.fold = function(o) {
+
+       return this.queue(function() {
+
+               // Create element
+               var el = $(this), props = ['position','top','bottom','left','right'];
+
+               // Set options
+               var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+               var size = o.options.size || 15; // Default fold size
+               var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
+               var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
+
+               // Adjust
+               $.effects.save(el, props); el.show(); // Save & Show
+               var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+               var widthFirst = ((mode == 'show') != horizFirst);
+               var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
+               var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
+               var percent = /([0-9]+)%/.exec(size);
+               if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
+               if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
+
+               // Animation
+               var animation1 = {}, animation2 = {};
+               animation1[ref[0]] = mode == 'show' ? distance[0] : size;
+               animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
+
+               // Animate
+               wrapper.animate(animation1, duration, o.options.easing)
+               .animate(animation2, duration, o.options.easing, function() {
+                       if(mode == 'hide') el.hide(); // Hide
+                       $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+                       if(o.callback) o.callback.apply(el[0], arguments); // Callback
+                       el.dequeue();
+               });
+
+       });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Highlight 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Highlight
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.highlight = function(o) {
+       return this.queue(function() {
+               var elem = $(this),
+                       props = ['backgroundImage', 'backgroundColor', 'opacity'],
+                       mode = $.effects.setMode(elem, o.options.mode || 'show'),
+                       animation = {
+                               backgroundColor: elem.css('backgroundColor')
+                       };
+
+               if (mode == 'hide') {
+                       animation.opacity = 0;
+               }
+
+               $.effects.save(elem, props);
+               elem
+                       .show()
+                       .css({
+                               backgroundImage: 'none',
+                               backgroundColor: o.options.color || '#ffff99'
+                       })
+                       .animate(animation, {
+                               queue: false,
+                               duration: o.duration,
+                               easing: o.options.easing,
+                               complete: function() {
+                                       (mode == 'hide' && elem.hide());
+                                       $.effects.restore(elem, props);
+                                       (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
+                                       (o.callback && o.callback.apply(this, arguments));
+                                       elem.dequeue();
+                               }
+                       });
+       });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Pulsate 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Pulsate
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.pulsate = function(o) {
+       return this.queue(function() {
+               var elem = $(this),
+                       mode = $.effects.setMode(elem, o.options.mode || 'show');
+                       times = ((o.options.times || 5) * 2) - 1;
+                       duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
+                       isVisible = elem.is(':visible'),
+                       animateTo = 0;
+
+               if (!isVisible) {
+                       elem.css('opacity', 0).show();
+                       animateTo = 1;
+               }
+
+               if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
+                       times--;
+               }
+
+               for (var i = 0; i < times; i++) {
+                       elem.animate({ opacity: animateTo }, duration, o.options.easing);
+                       animateTo = (animateTo + 1) % 2;
+               }
+
+               elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
+                       if (animateTo == 0) {
+                               elem.hide();
+                       }
+                       (o.callback && o.callback.apply(this, arguments));
+               });
+
+               elem
+                       .queue('fx', function() { elem.dequeue(); })
+                       .dequeue();
+       });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Scale 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Scale
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.puff = function(o) {
+       return this.queue(function() {
+               var elem = $(this),
+                       mode = $.effects.setMode(elem, o.options.mode || 'hide'),
+                       percent = parseInt(o.options.percent, 10) || 150,
+                       factor = percent / 100,
+                       original = { height: elem.height(), width: elem.width() };
+
+               $.extend(o.options, {
+                       fade: true,
+                       mode: mode,
+                       percent: mode == 'hide' ? percent : 100,
+                       from: mode == 'hide'
+                               ? original
+                               : {
+                                       height: original.height * factor,
+                                       width: original.width * factor
+                               }
+               });
+
+               elem.effect('scale', o.options, o.duration, o.callback);
+               elem.dequeue();
+       });
+};
+
+$.effects.scale = function(o) {
+
+       return this.queue(function() {
+
+               // Create element
+               var el = $(this);
+
+               // Set options
+               var options = $.extend(true, {}, o.options);
+               var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+               var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
+               var direction = o.options.direction || 'both'; // Set default axis
+               var origin = o.options.origin; // The origin of the scaling
+               if (mode != 'effect') { // Set default origin and restore for show/hide
+                       options.origin = origin || ['middle','center'];
+                       options.restore = true;
+               }
+               var original = {height: el.height(), width: el.width()}; // Save original
+               el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
+
+               // Adjust
+               var factor = { // Set scaling factor
+                       y: direction != 'horizontal' ? (percent / 100) : 1,
+                       x: direction != 'vertical' ? (percent / 100) : 1
+               };
+               el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
+
+               if (o.options.fade) { // Fade option to support puff
+                       if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
+                       if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
+               };
+
+               // Animation
+               options.from = el.from; options.to = el.to; options.mode = mode;
+
+               // Animate
+               el.effect('size', options, o.duration, o.callback);
+               el.dequeue();
+       });
+
+};
+
+$.effects.size = function(o) {
+
+       return this.queue(function() {
+
+               // Create element
+               var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
+               var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
+               var props2 = ['width','height','overflow']; // Copy for children
+               var cProps = ['fontSize'];
+               var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
+               var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
+
+               // Set options
+               var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+               var restore = o.options.restore || false; // Default restore
+               var scale = o.options.scale || 'both'; // Default scale mode
+               var origin = o.options.origin; // The origin of the sizing
+               var original = {height: el.height(), width: el.width()}; // Save original
+               el.from = o.options.from || original; // Default from state
+               el.to = o.options.to || original; // Default to state
+               // Adjust
+               if (origin) { // Calculate baseline shifts
+                       var baseline = $.effects.getBaseline(origin, original);
+                       el.from.top = (original.height - el.from.height) * baseline.y;
+                       el.from.left = (original.width - el.from.width) * baseline.x;
+                       el.to.top = (original.height - el.to.height) * baseline.y;
+                       el.to.left = (original.width - el.to.width) * baseline.x;
+               };
+               var factor = { // Set scaling factor
+                       from: {y: el.from.height / original.height, x: el.from.width / original.width},
+                       to: {y: el.to.height / original.height, x: el.to.width / original.width}
+               };
+               if (scale == 'box' || scale == 'both') { // Scale the css box
+                       if (factor.from.y != factor.to.y) { // Vertical props scaling
+                               props = props.concat(vProps);
+                               el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
+                               el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
+                       };
+                       if (factor.from.x != factor.to.x) { // Horizontal props scaling
+                               props = props.concat(hProps);
+                               el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
+                               el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
+                       };
+               };
+               if (scale == 'content' || scale == 'both') { // Scale the content
+                       if (factor.from.y != factor.to.y) { // Vertical props scaling
+                               props = props.concat(cProps);
+                               el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
+                               el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
+                       };
+               };
+               $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
+               $.effects.createWrapper(el); // Create Wrapper
+               el.css('overflow','hidden').css(el.from); // Shift
+
+               // Animate
+               if (scale == 'content' || scale == 'both') { // Scale the children
+                       vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
+                       hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
+                       props2 = props.concat(vProps).concat(hProps); // Concat
+                       el.find("*[width]").each(function(){
+                               child = $(this);
+                               if (restore) $.effects.save(child, props2);
+                               var c_original = {height: child.height(), width: child.width()}; // Save original
+                               child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
+                               child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
+                               if (factor.from.y != factor.to.y) { // Vertical props scaling
+                                       child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
+                                       child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
+                               };
+                               if (factor.from.x != factor.to.x) { // Horizontal props scaling
+                                       child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
+                                       child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
+                               };
+                               child.css(child.from); // Shift children
+                               child.animate(child.to, o.duration, o.options.easing, function(){
+                                       if (restore) $.effects.restore(child, props2); // Restore children
+                               }); // Animate children
+                       });
+               };
+
+               // Animate
+               el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+                       if (el.to.opacity === 0) {
+                               el.css('opacity', el.from.opacity);
+                       }
+                       if(mode == 'hide') el.hide(); // Hide
+                       $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
+                       if(o.callback) o.callback.apply(this, arguments); // Callback
+                       el.dequeue();
+               }});
+
+       });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Shake 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Shake
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.shake = function(o) {
+
+       return this.queue(function() {
+
+               // Create element
+               var el = $(this), props = ['position','top','bottom','left','right'];
+
+               // Set options
+               var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+               var direction = o.options.direction || 'left'; // Default direction
+               var distance = o.options.distance || 20; // Default distance
+               var times = o.options.times || 3; // Default # of times
+               var speed = o.duration || o.options.duration || 140; // Default speed per shake
+
+               // Adjust
+               $.effects.save(el, props); el.show(); // Save & Show
+               $.effects.createWrapper(el); // Create Wrapper
+               var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+               var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+
+               // Animation
+               var animation = {}, animation1 = {}, animation2 = {};
+               animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
+               animation1[ref] = (motion == 'pos' ? '+=' : '-=')  + distance * 2;
+               animation2[ref] = (motion == 'pos' ? '-=' : '+=')  + distance * 2;
+
+               // Animate
+               el.animate(animation, speed, o.options.easing);
+               for (var i = 1; i < times; i++) { // Shakes
+                       el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
+               };
+               el.animate(animation1, speed, o.options.easing).
+               animate(animation, speed / 2, o.options.easing, function(){ // Last shake
+                       $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+                       if(o.callback) o.callback.apply(this, arguments); // Callback
+               });
+               el.queue('fx', function() { el.dequeue(); });
+               el.dequeue();
+       });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Slide 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Slide
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.slide = function(o) {
+
+       return this.queue(function() {
+
+               // Create element
+               var el = $(this), props = ['position','top','bottom','left','right'];
+
+               // Set options
+               var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
+               var direction = o.options.direction || 'left'; // Default Direction
+
+               // Adjust
+               $.effects.save(el, props); el.show(); // Save & Show
+               $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+               var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+               var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+               var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
+               if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
+
+               // Animation
+               var animation = {};
+               animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
+
+               // Animate
+               el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+                       if(mode == 'hide') el.hide(); // Hide
+                       $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+                       if(o.callback) o.callback.apply(this, arguments); // Callback
+                       el.dequeue();
+               }});
+
+       });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Transfer 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Transfer
+ *
+ * Depends:
+ *     jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.transfer = function(o) {
+       return this.queue(function() {
+               var elem = $(this),
+                       target = $(o.options.to),
+                       endPosition = target.offset(),
+                       animation = {
+                               top: endPosition.top,
+                               left: endPosition.left,
+                               height: target.innerHeight(),
+                               width: target.innerWidth()
+                       },
+                       startPosition = elem.offset(),
+                       transfer = $('<div class="ui-effects-transfer"></div>')
+                               .appendTo(document.body)
+                               .addClass(o.options.className)
+                               .css({
+                                       top: startPosition.top,
+                                       left: startPosition.left,
+                                       height: elem.innerHeight(),
+                                       width: elem.innerWidth(),
+                                       position: 'absolute'
+                               })
+                               .animate(animation, o.duration, o.options.easing, function() {
+                                       transfer.remove();
+                                       (o.callback && o.callback.apply(elem[0], arguments));
+                                       elem.dequeue();
+                               });
+       });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Accordion 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget( "ui.accordion", {
+       options: {
+               active: 0,
+               animated: "slide",
+               autoHeight: true,
+               clearStyle: false,
+               collapsible: false,
+               event: "click",
+               fillSpace: false,
+               header: "> li > :first-child,> :not(li):even",
+               icons: {
+                       header: "ui-icon-triangle-1-e",
+                       headerSelected: "ui-icon-triangle-1-s"
+               },
+               navigation: false,
+               navigationFilter: function() {
+                       return this.href.toLowerCase() === location.href.toLowerCase();
+               }
+       },
+
+       _create: function() {
+               var self = this,
+                       options = self.options;
+
+               self.running = 0;
+
+               self.element
+                       .addClass( "ui-accordion ui-widget ui-helper-reset" )
+                       // in lack of child-selectors in CSS
+                       // we need to mark top-LIs in a UL-accordion for some IE-fix
+                       .children( "li" )
+                               .addClass( "ui-accordion-li-fix" );
+
+               self.headers = self.element.find( options.header )
+                       .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
+                       .bind( "mouseenter.accordion", function() {
+                               if ( options.disabled ) {
+                                       return;
+                               }
+                               $( this ).addClass( "ui-state-hover" );
+                       })
+                       .bind( "mouseleave.accordion", function() {
+                               if ( options.disabled ) {
+                                       return;
+                               }
+                               $( this ).removeClass( "ui-state-hover" );
+                       })
+                       .bind( "focus.accordion", function() {
+                               if ( options.disabled ) {
+                                       return;
+                               }
+                               $( this ).addClass( "ui-state-focus" );
+                       })
+                       .bind( "blur.accordion", function() {
+                               if ( options.disabled ) {
+                                       return;
+                               }
+                               $( this ).removeClass( "ui-state-focus" );
+                       });
+
+               self.headers.next()
+                       .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
+
+               if ( options.navigation ) {
+                       var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
+                       if ( current.length ) {
+                               var header = current.closest( ".ui-accordion-header" );
+                               if ( header.length ) {
+                                       // anchor within header
+                                       self.active = header;
+                               } else {
+                                       // anchor within content
+                                       self.active = current.closest( ".ui-accordion-content" ).prev();
+                               }
+                       }
+               }
+
+               self.active = self._findActive( self.active || options.active )
+                       .addClass( "ui-state-default ui-state-active" )
+                       .toggleClass( "ui-corner-all" )
+                       .toggleClass( "ui-corner-top" );
+               self.active.next().addClass( "ui-accordion-content-active" );
+
+               self._createIcons();
+               self.resize();
+               
+               // ARIA
+               self.element.attr( "role", "tablist" );
+
+               self.headers
+                       .attr( "role", "tab" )
+                       .bind( "keydown.accordion", function( event ) {
+                               return self._keydown( event );
+                       })
+                       .next()
+                               .attr( "role", "tabpanel" );
+
+               self.headers
+                       .not( self.active || "" )
+                       .attr({
+                               "aria-expanded": "false",
+                               "aria-selected": "false",
+                               tabIndex: -1
+                       })
+                       .next()
+                               .hide();
+
+               // make sure at least one header is in the tab order
+               if ( !self.active.length ) {
+                       self.headers.eq( 0 ).attr( "tabIndex", 0 );
+               } else {
+                       self.active
+                               .attr({
+                                       "aria-expanded": "true",
+                                       "aria-selected": "true",
+                                       tabIndex: 0
+                               });
+               }
+
+               // only need links in tab order for Safari
+               if ( !$.browser.safari ) {
+                       self.headers.find( "a" ).attr( "tabIndex", -1 );
+               }
+
+               if ( options.event ) {
+                       self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
+                               self._clickHandler.call( self, event, this );
+                               event.preventDefault();
+                       });
+               }
+       },
+
+       _createIcons: function() {
+               var options = this.options;
+               if ( options.icons ) {
+                       $( "<span></span>" )
+                               .addClass( "ui-icon " + options.icons.header )
+                               .prependTo( this.headers );
+                       this.active.children( ".ui-icon" )
+                               .toggleClass(options.icons.header)
+                               .toggleClass(options.icons.headerSelected);
+                       this.element.addClass( "ui-accordion-icons" );
+               }
+       },
+
+       _destroyIcons: function() {
+               this.headers.children( ".ui-icon" ).remove();
+               this.element.removeClass( "ui-accordion-icons" );
+       },
+
+       destroy: function() {
+               var options = this.options;
+
+               this.element
+                       .removeClass( "ui-accordion ui-widget ui-helper-reset" )
+                       .removeAttr( "role" );
+
+               this.headers
+                       .unbind( ".accordion" )
+                       .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-expanded" )
+                       .removeAttr( "aria-selected" )
+                       .removeAttr( "tabIndex" );
+
+               this.headers.find( "a" ).removeAttr( "tabIndex" );
+               this._destroyIcons();
+               var contents = this.headers.next()
+                       .css( "display", "" )
+                       .removeAttr( "role" )
+                       .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
+               if ( options.autoHeight || options.fillHeight ) {
+                       contents.css( "height", "" );
+               }
+
+               return $.Widget.prototype.destroy.call( this );
+       },
+
+       _setOption: function( key, value ) {
+               $.Widget.prototype._setOption.apply( this, arguments );
+                       
+               if ( key == "active" ) {
+                       this.activate( value );
+               }
+               if ( key == "icons" ) {
+                       this._destroyIcons();
+                       if ( value ) {
+                               this._createIcons();
+                       }
+               }
+               // #5332 - opacity doesn't cascade to positioned elements in IE
+               // so we need to add the disabled class to the headers and panels
+               if ( key == "disabled" ) {
+                       this.headers.add(this.headers.next())
+                               [ value ? "addClass" : "removeClass" ](
+                                       "ui-accordion-disabled ui-state-disabled" );
+               }
+       },
+
+       _keydown: function( event ) {
+               if ( this.options.disabled || event.altKey || event.ctrlKey ) {
+                       return;
+               }
+
+               var keyCode = $.ui.keyCode,
+                       length = this.headers.length,
+                       currentIndex = this.headers.index( event.target ),
+                       toFocus = false;
+
+               switch ( event.keyCode ) {
+                       case keyCode.RIGHT:
+                       case keyCode.DOWN:
+                               toFocus = this.headers[ ( currentIndex + 1 ) % length ];
+                               break;
+                       case keyCode.LEFT:
+                       case keyCode.UP:
+                               toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
+                               break;
+                       case keyCode.SPACE:
+                       case keyCode.ENTER:
+                               this._clickHandler( { target: event.target }, event.target );
+                               event.preventDefault();
+               }
+
+               if ( toFocus ) {
+                       $( event.target ).attr( "tabIndex", -1 );
+                       $( toFocus ).attr( "tabIndex", 0 );
+                       toFocus.focus();
+                       return false;
+               }
+
+               return true;
+       },
+
+       resize: function() {
+               var options = this.options,
+                       maxHeight;
+
+               if ( options.fillSpace ) {
+                       if ( $.browser.msie ) {
+                               var defOverflow = this.element.parent().css( "overflow" );
+                               this.element.parent().css( "overflow", "hidden");
+                       }
+                       maxHeight = this.element.parent().height();
+                       if ($.browser.msie) {
+                               this.element.parent().css( "overflow", defOverflow );
+                       }
+
+                       this.headers.each(function() {
+                               maxHeight -= $( this ).outerHeight( true );
+                       });
+
+                       this.headers.next()
+                               .each(function() {
+                                       $( this ).height( Math.max( 0, maxHeight -
+                                               $( this ).innerHeight() + $( this ).height() ) );
+                               })
+                               .css( "overflow", "auto" );
+               } else if ( options.autoHeight ) {
+                       maxHeight = 0;
+                       this.headers.next()
+                               .each(function() {
+                                       maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
+                               })
+                               .height( maxHeight );
+               }
+
+               return this;
+       },
+
+       activate: function( index ) {
+               // TODO this gets called on init, changing the option without an explicit call for that
+               this.options.active = index;
+               // call clickHandler with custom event
+               var active = this._findActive( index )[ 0 ];
+               this._clickHandler( { target: active }, active );
+
+               return this;
+       },
+
+       _findActive: function( selector ) {
+               return selector
+                       ? typeof selector === "number"
+                               ? this.headers.filter( ":eq(" + selector + ")" )
+                               : this.headers.not( this.headers.not( selector ) )
+                       : selector === false
+                               ? $( [] )
+                               : this.headers.filter( ":eq(0)" );
+       },
+
+       // TODO isn't event.target enough? why the separate target argument?
+       _clickHandler: function( event, target ) {
+               var options = this.options;
+               if ( options.disabled ) {
+                       return;
+               }
+
+               // called only when using activate(false) to close all parts programmatically
+               if ( !event.target ) {
+                       if ( !options.collapsible ) {
+                               return;
+                       }
+                       this.active
+                               .removeClass( "ui-state-active ui-corner-top" )
+                               .addClass( "ui-state-default ui-corner-all" )
+                               .children( ".ui-icon" )
+                                       .removeClass( options.icons.headerSelected )
+                                       .addClass( options.icons.header );
+                       this.active.next().addClass( "ui-accordion-content-active" );
+                       var toHide = this.active.next(),
+                               data = {
+                                       options: options,
+                                       newHeader: $( [] ),
+                                       oldHeader: options.active,
+                                       newContent: $( [] ),
+                                       oldContent: toHide
+                               },
+                               toShow = ( this.active = $( [] ) );
+                       this._toggle( toShow, toHide, data );
+                       return;
+               }
+
+               // get the click target
+               var clicked = $( event.currentTarget || target ),
+                       clickedIsActive = clicked[0] === this.active[0];
+
+               // TODO the option is changed, is that correct?
+               // TODO if it is correct, shouldn't that happen after determining that the click is valid?
+               options.active = options.collapsible && clickedIsActive ?
+                       false :
+                       this.headers.index( clicked );
+
+               // if animations are still active, or the active header is the target, ignore click
+               if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
+                       return;
+               }
+
+               // find elements to show and hide
+               var active = this.active,
+                       toShow = clicked.next(),
+                       toHide = this.active.next(),
+                       data = {
+                               options: options,
+                               newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
+                               oldHeader: this.active,
+                               newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
+                               oldContent: toHide
+                       },
+                       down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
+
+               // when the call to ._toggle() comes after the class changes
+               // it causes a very odd bug in IE 8 (see #6720)
+               this.active = clickedIsActive ? $([]) : clicked;
+               this._toggle( toShow, toHide, data, clickedIsActive, down );
+
+               // switch classes
+               active
+                       .removeClass( "ui-state-active ui-corner-top" )
+                       .addClass( "ui-state-default ui-corner-all" )
+                       .children( ".ui-icon" )
+                               .removeClass( options.icons.headerSelected )
+                               .addClass( options.icons.header );
+               if ( !clickedIsActive ) {
+                       clicked
+                               .removeClass( "ui-state-default ui-corner-all" )
+                               .addClass( "ui-state-active ui-corner-top" )
+                               .children( ".ui-icon" )
+                                       .removeClass( options.icons.header )
+                                       .addClass( options.icons.headerSelected );
+                       clicked
+                               .next()
+                               .addClass( "ui-accordion-content-active" );
+               }
+
+               return;
+       },
+
+       _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
+               var self = this,
+                       options = self.options;
+
+               self.toShow = toShow;
+               self.toHide = toHide;
+               self.data = data;
+
+               var complete = function() {
+                       if ( !self ) {
+                               return;
+                       }
+                       return self._completed.apply( self, arguments );
+               };
+
+               // trigger changestart event
+               self._trigger( "changestart", null, self.data );
+
+               // count elements to animate
+               self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
+
+               if ( options.animated ) {
+                       var animOptions = {};
+
+                       if ( options.collapsible && clickedIsActive ) {
+                               animOptions = {
+                                       toShow: $( [] ),
+                                       toHide: toHide,
+                                       complete: complete,
+                                       down: down,
+                                       autoHeight: options.autoHeight || options.fillSpace
+                               };
+                       } else {
+                               animOptions = {
+                                       toShow: toShow,
+                                       toHide: toHide,
+                                       complete: complete,
+                                       down: down,
+                                       autoHeight: options.autoHeight || options.fillSpace
+                               };
+                       }
+
+                       if ( !options.proxied ) {
+                               options.proxied = options.animated;
+                       }
+
+                       if ( !options.proxiedDuration ) {
+                               options.proxiedDuration = options.duration;
+                       }
+
+                       options.animated = $.isFunction( options.proxied ) ?
+                               options.proxied( animOptions ) :
+                               options.proxied;
+
+                       options.duration = $.isFunction( options.proxiedDuration ) ?
+                               options.proxiedDuration( animOptions ) :
+                               options.proxiedDuration;
+
+                       var animations = $.ui.accordion.animations,
+                               duration = options.duration,
+                               easing = options.animated;
+
+                       if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
+                               easing = "slide";
+                       }
+                       if ( !animations[ easing ] ) {
+                               animations[ easing ] = function( options ) {
+                                       this.slide( options, {
+                                               easing: easing,
+                                               duration: duration || 700
+                                       });
+                               };
+                       }
+
+                       animations[ easing ]( animOptions );
+               } else {
+                       if ( options.collapsible && clickedIsActive ) {
+                               toShow.toggle();
+                       } else {
+                               toHide.hide();
+                               toShow.show();
+                       }
+
+                       complete( true );
+               }
+
+               // TODO assert that the blur and focus triggers are really necessary, remove otherwise
+               toHide.prev()
+                       .attr({
+                               "aria-expanded": "false",
+                               "aria-selected": "false",
+                               tabIndex: -1
+                       })
+                       .blur();
+               toShow.prev()
+                       .attr({
+                               "aria-expanded": "true",
+                               "aria-selected": "true",
+                               tabIndex: 0
+                       })
+                       .focus();
+       },
+
+       _completed: function( cancel ) {
+               this.running = cancel ? 0 : --this.running;
+               if ( this.running ) {
+                       return;
+               }
+
+               if ( this.options.clearStyle ) {
+                       this.toShow.add( this.toHide ).css({
+                               height: "",
+                               overflow: ""
+                       });
+               }
+
+               // other classes are removed before the animation; this one needs to stay until completed
+               this.toHide.removeClass( "ui-accordion-content-active" );
+               // Work around for rendering bug in IE (#5421)
+               if ( this.toHide.length ) {
+                       this.toHide.parent()[0].className = this.toHide.parent()[0].className;
+               }
+
+               this._trigger( "change", null, this.data );
+       }
+});
+
+$.extend( $.ui.accordion, {
+       version: "1.8.12",
+       animations: {
+               slide: function( options, additions ) {
+                       options = $.extend({
+                               easing: "swing",
+                               duration: 300
+                       }, options, additions );
+                       if ( !options.toHide.size() ) {
+                               options.toShow.animate({
+                                       height: "show",
+                                       paddingTop: "show",
+                                       paddingBottom: "show"
+                               }, options );
+                               return;
+                       }
+                       if ( !options.toShow.size() ) {
+                               options.toHide.animate({
+                                       height: "hide",
+                                       paddingTop: "hide",
+                                       paddingBottom: "hide"
+                               }, options );
+                               return;
+                       }
+                       var overflow = options.toShow.css( "overflow" ),
+                               percentDone = 0,
+                               showProps = {},
+                               hideProps = {},
+                               fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
+                               originalWidth;
+                       // fix width before calculating height of hidden element
+                       var s = options.toShow;
+                       originalWidth = s[0].style.width;
+                       s.width( parseInt( s.parent().width(), 10 )
+                               - parseInt( s.css( "paddingLeft" ), 10 )
+                               - parseInt( s.css( "paddingRight" ), 10 )
+                               - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 )
+                               - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) );
+
+                       $.each( fxAttrs, function( i, prop ) {
+                               hideProps[ prop ] = "hide";
+
+                               var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
+                               showProps[ prop ] = {
+                                       value: parts[ 1 ],
+                                       unit: parts[ 2 ] || "px"
+                               };
+                       });
+                       options.toShow.css({ height: 0, overflow: "hidden" }).show();
+                       options.toHide
+                               .filter( ":hidden" )
+                                       .each( options.complete )
+                               .end()
+                               .filter( ":visible" )
+                               .animate( hideProps, {
+                               step: function( now, settings ) {
+                                       // only calculate the percent when animating height
+                                       // IE gets very inconsistent results when animating elements
+                                       // with small values, which is common for padding
+                                       if ( settings.prop == "height" ) {
+                                               percentDone = ( settings.end - settings.start === 0 ) ? 0 :
+                                                       ( settings.now - settings.start ) / ( settings.end - settings.start );
+                                       }
+
+                                       options.toShow[ 0 ].style[ settings.prop ] =
+                                               ( percentDone * showProps[ settings.prop ].value )
+                                               + showProps[ settings.prop ].unit;
+                               },
+                               duration: options.duration,
+                               easing: options.easing,
+                               complete: function() {
+                                       if ( !options.autoHeight ) {
+                                               options.toShow.css( "height", "" );
+                                       }
+                                       options.toShow.css({
+                                               width: originalWidth,
+                                               overflow: overflow
+                                       });
+                                       options.complete();
+                               }
+                       });
+               },
+               bounceslide: function( options ) {
+                       this.slide( options, {
+                               easing: options.down ? "easeOutBounce" : "swing",
+                               duration: options.down ? 1000 : 200
+                       });
+               }
+       }
+});
+
+})( jQuery );
+/*
+ * jQuery UI Autocomplete 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.widget.js
+ *     jquery.ui.position.js
+ */
+(function( $, undefined ) {
+
+// used to prevent race conditions with remote data sources
+var requestIndex = 0;
+
+$.widget( "ui.autocomplete", {
+       options: {
+               appendTo: "body",
+               autoFocus: false,
+               delay: 300,
+               minLength: 1,
+               position: {
+                       my: "left top",
+                       at: "left bottom",
+                       collision: "none"
+               },
+               source: null
+       },
+
+       pending: 0,
+
+       _create: function() {
+               var self = this,
+                       doc = this.element[ 0 ].ownerDocument,
+                       suppressKeyPress;
+
+               this.element
+                       .addClass( "ui-autocomplete-input" )
+                       .attr( "autocomplete", "off" )
+                       // TODO verify these actually work as intended
+                       .attr({
+                               role: "textbox",
+                               "aria-autocomplete": "list",
+                               "aria-haspopup": "true"
+                       })
+                       .bind( "keydown.autocomplete", function( event ) {
+                               if ( self.options.disabled || self.element.attr( "readonly" ) ) {
+                                       return;
+                               }
+
+                               suppressKeyPress = false;
+                               var keyCode = $.ui.keyCode;
+                               switch( event.keyCode ) {
+                               case keyCode.PAGE_UP:
+                                       self._move( "previousPage", event );
+                                       break;
+                               case keyCode.PAGE_DOWN:
+                                       self._move( "nextPage", event );
+                                       break;
+                               case keyCode.UP:
+                                       self._move( "previous", event );
+                                       // prevent moving cursor to beginning of text field in some browsers
+                                       event.preventDefault();
+                                       break;
+                               case keyCode.DOWN:
+                                       self._move( "next", event );
+                                       // prevent moving cursor to end of text field in some browsers
+                                       event.preventDefault();
+                                       break;
+                               case keyCode.ENTER:
+                               case keyCode.NUMPAD_ENTER:
+                                       // when menu is open and has focus
+                                       if ( self.menu.active ) {
+                                               // #6055 - Opera still allows the keypress to occur
+                                               // which causes forms to submit
+                                               suppressKeyPress = true;
+                                               event.preventDefault();
+                                       }
+                                       //passthrough - ENTER and TAB both select the current element
+                               case keyCode.TAB:
+                                       if ( !self.menu.active ) {
+                                               return;
+                                       }
+                                       self.menu.select( event );
+                                       break;
+                               case keyCode.ESCAPE:
+                                       self.element.val( self.term );
+                                       self.close( event );
+                                       break;
+                               default:
+                                       // keypress is triggered before the input value is changed
+                                       clearTimeout( self.searching );
+                                       self.searching = setTimeout(function() {
+                                               // only search if the value has changed
+                                               if ( self.term != self.element.val() ) {
+                                                       self.selectedItem = null;
+                                                       self.search( null, event );
+                                               }
+                                       }, self.options.delay );
+                                       break;
+                               }
+                       })
+                       .bind( "keypress.autocomplete", function( event ) {
+                               if ( suppressKeyPress ) {
+                                       suppressKeyPress = false;
+                                       event.preventDefault();
+                               }
+                       })
+                       .bind( "focus.autocomplete", function() {
+                               if ( self.options.disabled ) {
+                                       return;
+                               }
+
+                               self.selectedItem = null;
+                               self.previous = self.element.val();
+                       })
+                       .bind( "blur.autocomplete", function( event ) {
+                               if ( self.options.disabled ) {
+                                       return;
+                               }
+
+                               clearTimeout( self.searching );
+                               // clicks on the menu (or a button to trigger a search) will cause a blur event
+                               self.closing = setTimeout(function() {
+                                       self.close( event );
+                                       self._change( event );
+                               }, 150 );
+                       });
+               this._initSource();
+               this.response = function() {
+                       return self._response.apply( self, arguments );
+               };
+               this.menu = $( "<ul></ul>" )
+                       .addClass( "ui-autocomplete" )
+                       .appendTo( $( this.options.appendTo || "body", doc )[0] )
+                       // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
+                       .mousedown(function( event ) {
+                               // clicking on the scrollbar causes focus to shift to the body
+                               // but we can't detect a mouseup or a click immediately afterward
+                               // so we have to track the next mousedown and close the menu if
+                               // the user clicks somewhere outside of the autocomplete
+                               var menuElement = self.menu.element[ 0 ];
+                               if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
+                                       setTimeout(function() {
+                                               $( document ).one( 'mousedown', function( event ) {
+                                                       if ( event.target !== self.element[ 0 ] &&
+                                                               event.target !== menuElement &&
+                                                               !$.ui.contains( menuElement, event.target ) ) {
+                                                               self.close();
+                                                       }
+                                               });
+                                       }, 1 );
+                               }
+
+                               // use another timeout to make sure the blur-event-handler on the input was already triggered
+                               setTimeout(function() {
+                                       clearTimeout( self.closing );
+                               }, 13);
+                       })
+                       .menu({
+                               focus: function( event, ui ) {
+                                       var item = ui.item.data( "item.autocomplete" );
+                                       if ( false !== self._trigger( "focus", event, { item: item } ) ) {
+                                               // use value to match what will end up in the input, if it was a key event
+                                               if ( /^key/.test(event.originalEvent.type) ) {
+                                                       self.element.val( item.value );
+                                               }
+                                       }
+                               },
+                               selected: function( event, ui ) {
+                                       var item = ui.item.data( "item.autocomplete" ),
+                                               previous = self.previous;
+
+                                       // only trigger when focus was lost (click on menu)
+                                       if ( self.element[0] !== doc.activeElement ) {
+                                               self.element.focus();
+                                               self.previous = previous;
+                                               // #6109 - IE triggers two focus events and the second
+                                               // is asynchronous, so we need to reset the previous
+                                               // term synchronously and asynchronously :-(
+                                               setTimeout(function() {
+                                                       self.previous = previous;
+                                                       self.selectedItem = item;
+                                               }, 1);
+                                       }
+
+                                       if ( false !== self._trigger( "select", event, { item: item } ) ) {
+                                               self.element.val( item.value );
+                                       }
+                                       // reset the term after the select event
+                                       // this allows custom select handling to work properly
+                                       self.term = self.element.val();
+
+                                       self.close( event );
+                                       self.selectedItem = item;
+                               },
+                               blur: function( event, ui ) {
+                                       // don't set the value of the text field if it's already correct
+                                       // this prevents moving the cursor unnecessarily
+                                       if ( self.menu.element.is(":visible") &&
+                                               ( self.element.val() !== self.term ) ) {
+                                               self.element.val( self.term );
+                                       }
+                               }
+                       })
+                       .zIndex( this.element.zIndex() + 1 )
+                       // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
+                       .css({ top: 0, left: 0 })
+                       .hide()
+                       .data( "menu" );
+               if ( $.fn.bgiframe ) {
+                        this.menu.element.bgiframe();
+               }
+       },
+
+       destroy: function() {
+               this.element
+                       .removeClass( "ui-autocomplete-input" )
+                       .removeAttr( "autocomplete" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-autocomplete" )
+                       .removeAttr( "aria-haspopup" );
+               this.menu.element.remove();
+               $.Widget.prototype.destroy.call( this );
+       },
+
+       _setOption: function( key, value ) {
+               $.Widget.prototype._setOption.apply( this, arguments );
+               if ( key === "source" ) {
+                       this._initSource();
+               }
+               if ( key === "appendTo" ) {
+                       this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
+               }
+               if ( key === "disabled" && value && this.xhr ) {
+                       this.xhr.abort();
+               }
+       },
+
+       _initSource: function() {
+               var self = this,
+                       array,
+                       url;
+               if ( $.isArray(this.options.source) ) {
+                       array = this.options.source;
+                       this.source = function( request, response ) {
+                               response( $.ui.autocomplete.filter(array, request.term) );
+                       };
+               } else if ( typeof this.options.source === "string" ) {
+                       url = this.options.source;
+                       this.source = function( request, response ) {
+                               if ( self.xhr ) {
+                                       self.xhr.abort();
+                               }
+                               self.xhr = $.ajax({
+                                       url: url,
+                                       data: request,
+                                       dataType: "json",
+                                       autocompleteRequest: ++requestIndex,
+                                       success: function( data, status ) {
+                                               if ( this.autocompleteRequest === requestIndex ) {
+                                                       response( data );
+                                               }
+                                       },
+                                       error: function() {
+                                               if ( this.autocompleteRequest === requestIndex ) {
+                                                       response( [] );
+                                               }
+                                       }
+                               });
+                       };
+               } else {
+                       this.source = this.options.source;
+               }
+       },
+
+       search: function( value, event ) {
+               value = value != null ? value : this.element.val();
+
+               // always save the actual value, not the one passed as an argument
+               this.term = this.element.val();
+
+               if ( value.length < this.options.minLength ) {
+                       return this.close( event );
+               }
+
+               clearTimeout( this.closing );
+               if ( this._trigger( "search", event ) === false ) {
+                       return;
+               }
+
+               return this._search( value );
+       },
+
+       _search: function( value ) {
+               this.pending++;
+               this.element.addClass( "ui-autocomplete-loading" );
+
+               this.source( { term: value }, this.response );
+       },
+
+       _response: function( content ) {
+               if ( !this.options.disabled && content && content.length ) {
+                       content = this._normalize( content );
+                       this._suggest( content );
+                       this._trigger( "open" );
+               } else {
+                       this.close();
+               }
+               this.pending--;
+               if ( !this.pending ) {
+                       this.element.removeClass( "ui-autocomplete-loading" );
+               }
+       },
+
+       close: function( event ) {
+               clearTimeout( this.closing );
+               if ( this.menu.element.is(":visible") ) {
+                       this.menu.element.hide();
+                       this.menu.deactivate();
+                       this._trigger( "close", event );
+               }
+       },
+       
+       _change: function( event ) {
+               if ( this.previous !== this.element.val() ) {
+                       this._trigger( "change", event, { item: this.selectedItem } );
+               }
+       },
+
+       _normalize: function( items ) {
+               // assume all items have the right format when the first item is complete
+               if ( items.length && items[0].label && items[0].value ) {
+                       return items;
+               }
+               return $.map( items, function(item) {
+                       if ( typeof item === "string" ) {
+                               return {
+                                       label: item,
+                                       value: item
+                               };
+                       }
+                       return $.extend({
+                               label: item.label || item.value,
+                               value: item.value || item.label
+                       }, item );
+               });
+       },
+
+       _suggest: function( items ) {
+               var ul = this.menu.element
+                       .empty()
+                       .zIndex( this.element.zIndex() + 1 );
+               this._renderMenu( ul, items );
+               // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
+               this.menu.deactivate();
+               this.menu.refresh();
+
+               // size and position menu
+               ul.show();
+               this._resizeMenu();
+               ul.position( $.extend({
+                       of: this.element
+               }, this.options.position ));
+
+               if ( this.options.autoFocus ) {
+                       this.menu.next( new $.Event("mouseover") );
+               }
+       },
+
+       _resizeMenu: function() {
+               var ul = this.menu.element;
+               ul.outerWidth( Math.max(
+                       ul.width( "" ).outerWidth(),
+                       this.element.outerWidth()
+               ) );
+       },
+
+       _renderMenu: function( ul, items ) {
+               var self = this;
+               $.each( items, function( index, item ) {
+                       self._renderItem( ul, item );
+               });
+       },
+
+       _renderItem: function( ul, item) {
+               return $( "<li></li>" )
+                       .data( "item.autocomplete", item )
+                       .append( $( "<a></a>" ).text( item.label ) )
+                       .appendTo( ul );
+       },
+
+       _move: function( direction, event ) {
+               if ( !this.menu.element.is(":visible") ) {
+                       this.search( null, event );
+                       return;
+               }
+               if ( this.menu.first() && /^previous/.test(direction) ||
+                               this.menu.last() && /^next/.test(direction) ) {
+                       this.element.val( this.term );
+                       this.menu.deactivate();
+                       return;
+               }
+               this.menu[ direction ]( event );
+       },
+
+       widget: function() {
+               return this.menu.element;
+       }
+});
+
+$.extend( $.ui.autocomplete, {
+       escapeRegex: function( value ) {
+               return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+       },
+       filter: function(array, term) {
+               var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
+               return $.grep( array, function(value) {
+                       return matcher.test( value.label || value.value || value );
+               });
+       }
+});
+
+}( jQuery ));
+
+/*
+ * jQuery UI Menu (not officially released)
+ * 
+ * This widget isn't yet finished and the API is subject to change. We plan to finish
+ * it for the next release. You're welcome to give it a try anyway and give us feedback,
+ * as long as you're okay with migrating your code later on. We can help with that, too.
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *  jquery.ui.widget.js
+ */
+(function($) {
+
+$.widget("ui.menu", {
+       _create: function() {
+               var self = this;
+               this.element
+                       .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
+                       .attr({
+                               role: "listbox",
+                               "aria-activedescendant": "ui-active-menuitem"
+                       })
+                       .click(function( event ) {
+                               if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
+                                       return;
+                               }
+                               // temporary
+                               event.preventDefault();
+                               self.select( event );
+                       });
+               this.refresh();
+       },
+       
+       refresh: function() {
+               var self = this;
+
+               // don't refresh list items that are already adapted
+               var items = this.element.children("li:not(.ui-menu-item):has(a)")
+                       .addClass("ui-menu-item")
+                       .attr("role", "menuitem");
+               
+               items.children("a")
+                       .addClass("ui-corner-all")
+                       .attr("tabindex", -1)
+                       // mouseenter doesn't work with event delegation
+                       .mouseenter(function( event ) {
+                               self.activate( event, $(this).parent() );
+                       })
+                       .mouseleave(function() {
+                               self.deactivate();
+                       });
+       },
+
+       activate: function( event, item ) {
+               this.deactivate();
+               if (this.hasScroll()) {
+                       var offset = item.offset().top - this.element.offset().top,
+                               scroll = this.element.attr("scrollTop"),
+                               elementHeight = this.element.height();
+                       if (offset < 0) {
+                               this.element.attr("scrollTop", scroll + offset);
+                       } else if (offset >= elementHeight) {
+                               this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
+                       }
+               }
+               this.active = item.eq(0)
+                       .children("a")
+                               .addClass("ui-state-hover")
+                               .attr("id", "ui-active-menuitem")
+                       .end();
+               this._trigger("focus", event, { item: item });
+       },
+
+       deactivate: function() {
+               if (!this.active) { return; }
+
+               this.active.children("a")
+                       .removeClass("ui-state-hover")
+                       .removeAttr("id");
+               this._trigger("blur");
+               this.active = null;
+       },
+
+       next: function(event) {
+               this.move("next", ".ui-menu-item:first", event);
+       },
+
+       previous: function(event) {
+               this.move("prev", ".ui-menu-item:last", event);
+       },
+
+       first: function() {
+               return this.active && !this.active.prevAll(".ui-menu-item").length;
+       },
+
+       last: function() {
+               return this.active && !this.active.nextAll(".ui-menu-item").length;
+       },
+
+       move: function(direction, edge, event) {
+               if (!this.active) {
+                       this.activate(event, this.element.children(edge));
+                       return;
+               }
+               var next = this.active[direction + "All"](".ui-menu-item").eq(0);
+               if (next.length) {
+                       this.activate(event, next);
+               } else {
+                       this.activate(event, this.element.children(edge));
+               }
+       },
+
+       // TODO merge with previousPage
+       nextPage: function(event) {
+               if (this.hasScroll()) {
+                       // TODO merge with no-scroll-else
+                       if (!this.active || this.last()) {
+                               this.activate(event, this.element.children(".ui-menu-item:first"));
+                               return;
+                       }
+                       var base = this.active.offset().top,
+                               height = this.element.height(),
+                               result = this.element.children(".ui-menu-item").filter(function() {
+                                       var close = $(this).offset().top - base - height + $(this).height();
+                                       // TODO improve approximation
+                                       return close < 10 && close > -10;
+                               });
+
+                       // TODO try to catch this earlier when scrollTop indicates the last page anyway
+                       if (!result.length) {
+                               result = this.element.children(".ui-menu-item:last");
+                       }
+                       this.activate(event, result);
+               } else {
+                       this.activate(event, this.element.children(".ui-menu-item")
+                               .filter(!this.active || this.last() ? ":first" : ":last"));
+               }
+       },
+
+       // TODO merge with nextPage
+       previousPage: function(event) {
+               if (this.hasScroll()) {
+                       // TODO merge with no-scroll-else
+                       if (!this.active || this.first()) {
+                               this.activate(event, this.element.children(".ui-menu-item:last"));
+                               return;
+                       }
+
+                       var base = this.active.offset().top,
+                               height = this.element.height();
+                               result = this.element.children(".ui-menu-item").filter(function() {
+                                       var close = $(this).offset().top - base + height - $(this).height();
+                                       // TODO improve approximation
+                                       return close < 10 && close > -10;
+                               });
+
+                       // TODO try to catch this earlier when scrollTop indicates the last page anyway
+                       if (!result.length) {
+                               result = this.element.children(".ui-menu-item:first");
+                       }
+                       this.activate(event, result);
+               } else {
+                       this.activate(event, this.element.children(".ui-menu-item")
+                               .filter(!this.active || this.first() ? ":last" : ":first"));
+               }
+       },
+
+       hasScroll: function() {
+               return this.element.height() < this.element.attr("scrollHeight");
+       },
+
+       select: function( event ) {
+               this._trigger("selected", event, { item: this.active });
+       }
+});
+
+}(jQuery));
+/*
+ * jQuery UI Button 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+var lastActive,
+       baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
+       stateClasses = "ui-state-hover ui-state-active ",
+       typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
+       formResetHandler = function( event ) {
+               $( ":ui-button", event.target.form ).each(function() {
+                       var inst = $( this ).data( "button" );
+                       setTimeout(function() {
+                               inst.refresh();
+                       }, 1 );
+               });
+       },
+       radioGroup = function( radio ) {
+               var name = radio.name,
+                       form = radio.form,
+                       radios = $( [] );
+               if ( name ) {
+                       if ( form ) {
+                               radios = $( form ).find( "[name='" + name + "']" );
+                       } else {
+                               radios = $( "[name='" + name + "']", radio.ownerDocument )
+                                       .filter(function() {
+                                               return !this.form;
+                                       });
+                       }
+               }
+               return radios;
+       };
+
+$.widget( "ui.button", {
+       options: {
+               disabled: null,
+               text: true,
+               label: null,
+               icons: {
+                       primary: null,
+                       secondary: null
+               }
+       },
+       _create: function() {
+               this.element.closest( "form" )
+                       .unbind( "reset.button" )
+                       .bind( "reset.button", formResetHandler );
+
+               if ( typeof this.options.disabled !== "boolean" ) {
+                       this.options.disabled = this.element.attr( "disabled" );
+               }
+
+               this._determineButtonType();
+               this.hasTitle = !!this.buttonElement.attr( "title" );
+
+               var self = this,
+                       options = this.options,
+                       toggleButton = this.type === "checkbox" || this.type === "radio",
+                       hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
+                       focusClass = "ui-state-focus";
+
+               if ( options.label === null ) {
+                       options.label = this.buttonElement.html();
+               }
+
+               if ( this.element.is( ":disabled" ) ) {
+                       options.disabled = true;
+               }
+
+               this.buttonElement
+                       .addClass( baseClasses )
+                       .attr( "role", "button" )
+                       .bind( "mouseenter.button", function() {
+                               if ( options.disabled ) {
+                                       return;
+                               }
+                               $( this ).addClass( "ui-state-hover" );
+                               if ( this === lastActive ) {
+                                       $( this ).addClass( "ui-state-active" );
+                               }
+                       })
+                       .bind( "mouseleave.button", function() {
+                               if ( options.disabled ) {
+                                       return;
+                               }
+                               $( this ).removeClass( hoverClass );
+                       })
+                       .bind( "focus.button", function() {
+                               // no need to check disabled, focus won't be triggered anyway
+                               $( this ).addClass( focusClass );
+                       })
+                       .bind( "blur.button", function() {
+                               $( this ).removeClass( focusClass );
+                       });
+
+               if ( toggleButton ) {
+                       this.element.bind( "change.button", function() {
+                               self.refresh();
+                       });
+               }
+
+               if ( this.type === "checkbox" ) {
+                       this.buttonElement.bind( "click.button", function() {
+                               if ( options.disabled ) {
+                                       return false;
+                               }
+                               $( this ).toggleClass( "ui-state-active" );
+                               self.buttonElement.attr( "aria-pressed", self.element[0].checked );
+                       });
+               } else if ( this.type === "radio" ) {
+                       this.buttonElement.bind( "click.button", function() {
+                               if ( options.disabled ) {
+                                       return false;
+                               }
+                               $( this ).addClass( "ui-state-active" );
+                               self.buttonElement.attr( "aria-pressed", true );
+
+                               var radio = self.element[ 0 ];
+                               radioGroup( radio )
+                                       .not( radio )
+                                       .map(function() {
+                                               return $( this ).button( "widget" )[ 0 ];
+                                       })
+                                       .removeClass( "ui-state-active" )
+                                       .attr( "aria-pressed", false );
+                       });
+               } else {
+                       this.buttonElement
+                               .bind( "mousedown.button", function() {
+                                       if ( options.disabled ) {
+                                               return false;
+                                       }
+                                       $( this ).addClass( "ui-state-active" );
+                                       lastActive = this;
+                                       $( document ).one( "mouseup", function() {
+                                               lastActive = null;
+                                       });
+                               })
+                               .bind( "mouseup.button", function() {
+                                       if ( options.disabled ) {
+                                               return false;
+                                       }
+                                       $( this ).removeClass( "ui-state-active" );
+                               })
+                               .bind( "keydown.button", function(event) {
+                                       if ( options.disabled ) {
+                                               return false;
+                                       }
+                                       if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
+                                               $( this ).addClass( "ui-state-active" );
+                                       }
+                               })
+                               .bind( "keyup.button", function() {
+                                       $( this ).removeClass( "ui-state-active" );
+                               });
+
+                       if ( this.buttonElement.is("a") ) {
+                               this.buttonElement.keyup(function(event) {
+                                       if ( event.keyCode === $.ui.keyCode.SPACE ) {
+                                               // TODO pass through original event correctly (just as 2nd argument doesn't work)
+                                               $( this ).click();
+                                       }
+                               });
+                       }
+               }
+
+               // TODO: pull out $.Widget's handling for the disabled option into
+               // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
+               // be overridden by individual plugins
+               this._setOption( "disabled", options.disabled );
+       },
+
+       _determineButtonType: function() {
+
+               if ( this.element.is(":checkbox") ) {
+                       this.type = "checkbox";
+               } else if ( this.element.is(":radio") ) {
+                       this.type = "radio";
+               } else if ( this.element.is("input") ) {
+                       this.type = "input";
+               } else {
+                       this.type = "button";
+               }
+
+               if ( this.type === "checkbox" || this.type === "radio" ) {
+                       // we don't search against the document in case the element
+                       // is disconnected from the DOM
+                       var ancestor = this.element.parents().filter(":last"),
+                               labelSelector = "label[for=" + this.element.attr("id") + "]";
+                       this.buttonElement = ancestor.find( labelSelector );
+                       if ( !this.buttonElement.length ) {
+                               ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
+                               this.buttonElement = ancestor.filter( labelSelector );
+                               if ( !this.buttonElement.length ) {
+                                       this.buttonElement = ancestor.find( labelSelector );
+                               }
+                       }
+                       this.element.addClass( "ui-helper-hidden-accessible" );
+
+                       var checked = this.element.is( ":checked" );
+                       if ( checked ) {
+                               this.buttonElement.addClass( "ui-state-active" );
+                       }
+                       this.buttonElement.attr( "aria-pressed", checked );
+               } else {
+                       this.buttonElement = this.element;
+               }
+       },
+
+       widget: function() {
+               return this.buttonElement;
+       },
+
+       destroy: function() {
+               this.element
+                       .removeClass( "ui-helper-hidden-accessible" );
+               this.buttonElement
+                       .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-pressed" )
+                       .html( this.buttonElement.find(".ui-button-text").html() );
+
+               if ( !this.hasTitle ) {
+                       this.buttonElement.removeAttr( "title" );
+               }
+
+               $.Widget.prototype.destroy.call( this );
+       },
+
+       _setOption: function( key, value ) {
+               $.Widget.prototype._setOption.apply( this, arguments );
+               if ( key === "disabled" ) {
+                       if ( value ) {
+                               this.element.attr( "disabled", true );
+                       } else {
+                               this.element.removeAttr( "disabled" );
+                       }
+               }
+               this._resetButton();
+       },
+
+       refresh: function() {
+               var isDisabled = this.element.is( ":disabled" );
+               if ( isDisabled !== this.options.disabled ) {
+                       this._setOption( "disabled", isDisabled );
+               }
+               if ( this.type === "radio" ) {
+                       radioGroup( this.element[0] ).each(function() {
+                               if ( $( this ).is( ":checked" ) ) {
+                                       $( this ).button( "widget" )
+                                               .addClass( "ui-state-active" )
+                                               .attr( "aria-pressed", true );
+                               } else {
+                                       $( this ).button( "widget" )
+                                               .removeClass( "ui-state-active" )
+                                               .attr( "aria-pressed", false );
+                               }
+                       });
+               } else if ( this.type === "checkbox" ) {
+                       if ( this.element.is( ":checked" ) ) {
+                               this.buttonElement
+                                       .addClass( "ui-state-active" )
+                                       .attr( "aria-pressed", true );
+                       } else {
+                               this.buttonElement
+                                       .removeClass( "ui-state-active" )
+                                       .attr( "aria-pressed", false );
+                       }
+               }
+       },
+
+       _resetButton: function() {
+               if ( this.type === "input" ) {
+                       if ( this.options.label ) {
+                               this.element.val( this.options.label );
+                       }
+                       return;
+               }
+               var buttonElement = this.buttonElement.removeClass( typeClasses ),
+                       buttonText = $( "<span></span>" )
+                               .addClass( "ui-button-text" )
+                               .html( this.options.label )
+                               .appendTo( buttonElement.empty() )
+                               .text(),
+                       icons = this.options.icons,
+                       multipleIcons = icons.primary && icons.secondary,
+                       buttonClasses = [];  
+
+               if ( icons.primary || icons.secondary ) {
+                       if ( this.options.text ) {
+                               buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
+                       }
+
+                       if ( icons.primary ) {
+                               buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
+                       }
+
+                       if ( icons.secondary ) {
+                               buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
+                       }
+
+                       if ( !this.options.text ) {
+                               buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
+
+                               if ( !this.hasTitle ) {
+                                       buttonElement.attr( "title", buttonText );
+                               }
+                       }
+               } else {
+                       buttonClasses.push( "ui-button-text-only" );
+               }
+               buttonElement.addClass( buttonClasses.join( " " ) );
+       }
+});
+
+$.widget( "ui.buttonset", {
+       options: {
+               items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
+       },
+
+       _create: function() {
+               this.element.addClass( "ui-buttonset" );
+       },
+       
+       _init: function() {
+               this.refresh();
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "disabled" ) {
+                       this.buttons.button( "option", key, value );
+               }
+
+               $.Widget.prototype._setOption.apply( this, arguments );
+       },
+       
+       refresh: function() {
+               this.buttons = this.element.find( this.options.items )
+                       .filter( ":ui-button" )
+                               .button( "refresh" )
+                       .end()
+                       .not( ":ui-button" )
+                               .button()
+                       .end()
+                       .map(function() {
+                               return $( this ).button( "widget" )[ 0 ];
+                       })
+                               .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
+                               .filter( ":first" )
+                                       .addClass( "ui-corner-left" )
+                               .end()
+                               .filter( ":last" )
+                                       .addClass( "ui-corner-right" )
+                               .end()
+                       .end();
+       },
+
+       destroy: function() {
+               this.element.removeClass( "ui-buttonset" );
+               this.buttons
+                       .map(function() {
+                               return $( this ).button( "widget" )[ 0 ];
+                       })
+                               .removeClass( "ui-corner-left ui-corner-right" )
+                       .end()
+                       .button( "destroy" );
+
+               $.Widget.prototype.destroy.call( this );
+       }
+});
+
+}( jQuery ) );
+/*
+ * jQuery UI Datepicker 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ */
+(function( $, undefined ) {
+
+$.extend($.ui, { datepicker: { version: "1.8.12" } });
+
+var PROP_NAME = 'datepicker';
+var dpuuid = new Date().getTime();
+
+/* Date picker manager.
+   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
+   Settings for (groups of) date pickers are maintained in an instance object,
+   allowing multiple different settings on the same page. */
+
+function Datepicker() {
+       this.debug = false; // Change this to true to start debugging
+       this._curInst = null; // The current instance in use
+       this._keyEvent = false; // If the last event was a key event
+       this._disabledInputs = []; // List of date picker inputs that have been disabled
+       this._datepickerShowing = false; // True if the popup picker is showing , false if not
+       this._inDialog = false; // True if showing within a "dialog", false if not
+       this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
+       this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
+       this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
+       this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
+       this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
+       this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
+       this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
+       this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
+       this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
+       this.regional = []; // Available regional settings, indexed by language code
+       this.regional[''] = { // Default regional settings
+               closeText: 'Done', // Display text for close link
+               prevText: 'Prev', // Display text for previous month link
+               nextText: 'Next', // Display text for next month link
+               currentText: 'Today', // Display text for current month link
+               monthNames: ['January','February','March','April','May','June',
+                       'July','August','September','October','November','December'], // Names of months for drop-down and formatting
+               monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
+               dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
+               dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
+               dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
+               weekHeader: 'Wk', // Column header for week of the year
+               dateFormat: 'mm/dd/yy', // See format options on parseDate
+               firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
+               isRTL: false, // True if right-to-left language, false if left-to-right
+               showMonthAfterYear: false, // True if the year select precedes month, false for month then year
+               yearSuffix: '' // Additional text to append to the year in the month headers
+       };
+       this._defaults = { // Global defaults for all the date picker instances
+               showOn: 'focus', // 'focus' for popup on focus,
+                       // 'button' for trigger button, or 'both' for either
+               showAnim: 'fadeIn', // Name of jQuery animation for popup
+               showOptions: {}, // Options for enhanced animations
+               defaultDate: null, // Used when field is blank: actual date,
+                       // +/-number for offset from today, null for today
+               appendText: '', // Display text following the input box, e.g. showing the format
+               buttonText: '...', // Text for trigger button
+               buttonImage: '', // URL for trigger button image
+               buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
+               hideIfNoPrevNext: false, // True to hide next/previous month links
+                       // if not applicable, false to just disable them
+               navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
+               gotoCurrent: false, // True if today link goes back to current selection instead
+               changeMonth: false, // True if month can be selected directly, false if only prev/next
+               changeYear: false, // True if year can be selected directly, false if only prev/next
+               yearRange: 'c-10:c+10', // Range of years to display in drop-down,
+                       // either relative to today's year (-nn:+nn), relative to currently displayed year
+                       // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
+               showOtherMonths: false, // True to show dates in other months, false to leave blank
+               selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
+               showWeek: false, // True to show week of the year, false to not show it
+               calculateWeek: this.iso8601Week, // How to calculate the week of the year,
+                       // takes a Date and returns the number of the week for it
+               shortYearCutoff: '+10', // Short year values < this are in the current century,
+                       // > this are in the previous century,
+                       // string value starting with '+' for current year + value
+               minDate: null, // The earliest selectable date, or null for no limit
+               maxDate: null, // The latest selectable date, or null for no limit
+               duration: 'fast', // Duration of display/closure
+               beforeShowDay: null, // Function that takes a date and returns an array with
+                       // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
+                       // [2] = cell title (optional), e.g. $.datepicker.noWeekends
+               beforeShow: null, // Function that takes an input field and
+                       // returns a set of custom settings for the date picker
+               onSelect: null, // Define a callback function when a date is selected
+               onChangeMonthYear: null, // Define a callback function when the month or year is changed
+               onClose: null, // Define a callback function when the datepicker is closed
+               numberOfMonths: 1, // Number of months to show at a time
+               showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
+               stepMonths: 1, // Number of months to step back/forward
+               stepBigMonths: 12, // Number of months to step back/forward for the big links
+               altField: '', // Selector for an alternate field to store selected dates into
+               altFormat: '', // The date format to use for the alternate field
+               constrainInput: true, // The input is constrained by the current date format
+               showButtonPanel: false, // True to show button panel, false to not show it
+               autoSize: false // True to size the input for the date format, false to leave as is
+       };
+       $.extend(this._defaults, this.regional['']);
+       this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>');
+}
+
+$.extend(Datepicker.prototype, {
+       /* Class name added to elements to indicate already configured with a date picker. */
+       markerClassName: 'hasDatepicker',
+
+       /* Debug logging (if enabled). */
+       log: function () {
+               if (this.debug)
+                       console.log.apply('', arguments);
+       },
+       
+       // TODO rename to "widget" when switching to widget factory
+       _widgetDatepicker: function() {
+               return this.dpDiv;
+       },
+
+       /* Override the default settings for all instances of the date picker.
+          @param  settings  object - the new settings to use as defaults (anonymous object)
+          @return the manager object */
+       setDefaults: function(settings) {
+               extendRemove(this._defaults, settings || {});
+               return this;
+       },
+
+       /* Attach the date picker to a jQuery selection.
+          @param  target    element - the target input field or division or span
+          @param  settings  object - the new settings to use for this date picker instance (anonymous) */
+       _attachDatepicker: function(target, settings) {
+               // check for settings on the control itself - in namespace 'date:'
+               var inlineSettings = null;
+               for (var attrName in this._defaults) {
+                       var attrValue = target.getAttribute('date:' + attrName);
+                       if (attrValue) {
+                               inlineSettings = inlineSettings || {};
+                               try {
+                                       inlineSettings[attrName] = eval(attrValue);
+                               } catch (err) {
+                                       inlineSettings[attrName] = attrValue;
+                               }
+                       }
+               }
+               var nodeName = target.nodeName.toLowerCase();
+               var inline = (nodeName == 'div' || nodeName == 'span');
+               if (!target.id) {
+                       this.uuid += 1;
+                       target.id = 'dp' + this.uuid;
+               }
+               var inst = this._newInst($(target), inline);
+               inst.settings = $.extend({}, settings || {}, inlineSettings || {});
+               if (nodeName == 'input') {
+                       this._connectDatepicker(target, inst);
+               } else if (inline) {
+                       this._inlineDatepicker(target, inst);
+               }
+       },
+
+       /* Create a new instance object. */
+       _newInst: function(target, inline) {
+               var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
+               return {id: id, input: target, // associated target
+                       selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
+                       drawMonth: 0, drawYear: 0, // month being drawn
+                       inline: inline, // is datepicker inline or not
+                       dpDiv: (!inline ? this.dpDiv : // presentation div
+                       $('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))};
+       },
+
+       /* Attach the date picker to an input field. */
+       _connectDatepicker: function(target, inst) {
+               var input = $(target);
+               inst.append = $([]);
+               inst.trigger = $([]);
+               if (input.hasClass(this.markerClassName))
+                       return;
+               this._attachments(input, inst);
+               input.addClass(this.markerClassName).keydown(this._doKeyDown).
+                       keypress(this._doKeyPress).keyup(this._doKeyUp).
+                       bind("setData.datepicker", function(event, key, value) {
+                               inst.settings[key] = value;
+                       }).bind("getData.datepicker", function(event, key) {
+                               return this._get(inst, key);
+                       });
+               this._autoSize(inst);
+               $.data(target, PROP_NAME, inst);
+       },
+
+       /* Make attachments based on settings. */
+       _attachments: function(input, inst) {
+               var appendText = this._get(inst, 'appendText');
+               var isRTL = this._get(inst, 'isRTL');
+               if (inst.append)
+                       inst.append.remove();
+               if (appendText) {
+                       inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
+                       input[isRTL ? 'before' : 'after'](inst.append);
+               }
+               input.unbind('focus', this._showDatepicker);
+               if (inst.trigger)
+                       inst.trigger.remove();
+               var showOn = this._get(inst, 'showOn');
+               if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
+                       input.focus(this._showDatepicker);
+               if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
+                       var buttonText = this._get(inst, 'buttonText');
+                       var buttonImage = this._get(inst, 'buttonImage');
+                       inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
+                               $('<img/>').addClass(this._triggerClass).
+                                       attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
+                               $('<button type="button"></button>').addClass(this._triggerClass).
+                                       html(buttonImage == '' ? buttonText : $('<img/>').attr(
+                                       { src:buttonImage, alt:buttonText, title:buttonText })));
+                       input[isRTL ? 'before' : 'after'](inst.trigger);
+                       inst.trigger.click(function() {
+                               if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
+                                       $.datepicker._hideDatepicker();
+                               else
+                                       $.datepicker._showDatepicker(input[0]);
+                               return false;
+                       });
+               }
+       },
+
+       /* Apply the maximum length for the date format. */
+       _autoSize: function(inst) {
+               if (this._get(inst, 'autoSize') && !inst.inline) {
+                       var date = new Date(2009, 12 - 1, 20); // Ensure double digits
+                       var dateFormat = this._get(inst, 'dateFormat');
+                       if (dateFormat.match(/[DM]/)) {
+                               var findMax = function(names) {
+                                       var max = 0;
+                                       var maxI = 0;
+                                       for (var i = 0; i < names.length; i++) {
+                                               if (names[i].length > max) {
+                                                       max = names[i].length;
+                                                       maxI = i;
+                                               }
+                                       }
+                                       return maxI;
+                               };
+                               date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
+                                       'monthNames' : 'monthNamesShort'))));
+                               date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
+                                       'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
+                       }
+                       inst.input.attr('size', this._formatDate(inst, date).length);
+               }
+       },
+
+       /* Attach an inline date picker to a div. */
+       _inlineDatepicker: function(target, inst) {
+               var divSpan = $(target);
+               if (divSpan.hasClass(this.markerClassName))
+                       return;
+               divSpan.addClass(this.markerClassName).append(inst.dpDiv).
+                       bind("setData.datepicker", function(event, key, value){
+                               inst.settings[key] = value;
+                       }).bind("getData.datepicker", function(event, key){
+                               return this._get(inst, key);
+                       });
+               $.data(target, PROP_NAME, inst);
+               this._setDate(inst, this._getDefaultDate(inst), true);
+               this._updateDatepicker(inst);
+               this._updateAlternate(inst);
+               inst.dpDiv.show();
+       },
+
+       /* Pop-up the date picker in a "dialog" box.
+          @param  input     element - ignored
+          @param  date      string or Date - the initial date to display
+          @param  onSelect  function - the function to call when a date is selected
+          @param  settings  object - update the dialog date picker instance's settings (anonymous object)
+          @param  pos       int[2] - coordinates for the dialog's position within the screen or
+                            event - with x/y coordinates or
+                            leave empty for default (screen centre)
+          @return the manager object */
+       _dialogDatepicker: function(input, date, onSelect, settings, pos) {
+               var inst = this._dialogInst; // internal instance
+               if (!inst) {
+                       this.uuid += 1;
+                       var id = 'dp' + this.uuid;
+                       this._dialogInput = $('<input type="text" id="' + id +
+                               '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
+                       this._dialogInput.keydown(this._doKeyDown);
+                       $('body').append(this._dialogInput);
+                       inst = this._dialogInst = this._newInst(this._dialogInput, false);
+                       inst.settings = {};
+                       $.data(this._dialogInput[0], PROP_NAME, inst);
+               }
+               extendRemove(inst.settings, settings || {});
+               date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
+               this._dialogInput.val(date);
+
+               this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
+               if (!this._pos) {
+                       var browserWidth = document.documentElement.clientWidth;
+                       var browserHeight = document.documentElement.clientHeight;
+                       var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
+                       var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
+                       this._pos = // should use actual width/height below
+                               [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
+               }
+
+               // move input on screen for focus, but hidden behind dialog
+               this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
+               inst.settings.onSelect = onSelect;
+               this._inDialog = true;
+               this.dpDiv.addClass(this._dialogClass);
+               this._showDatepicker(this._dialogInput[0]);
+               if ($.blockUI)
+                       $.blockUI(this.dpDiv);
+               $.data(this._dialogInput[0], PROP_NAME, inst);
+               return this;
+       },
+
+       /* Detach a datepicker from its control.
+          @param  target    element - the target input field or division or span */
+       _destroyDatepicker: function(target) {
+               var $target = $(target);
+               var inst = $.data(target, PROP_NAME);
+               if (!$target.hasClass(this.markerClassName)) {
+                       return;
+               }
+               var nodeName = target.nodeName.toLowerCase();
+               $.removeData(target, PROP_NAME);
+               if (nodeName == 'input') {
+                       inst.append.remove();
+                       inst.trigger.remove();
+                       $target.removeClass(this.markerClassName).
+                               unbind('focus', this._showDatepicker).
+                               unbind('keydown', this._doKeyDown).
+                               unbind('keypress', this._doKeyPress).
+                               unbind('keyup', this._doKeyUp);
+               } else if (nodeName == 'div' || nodeName == 'span')
+                       $target.removeClass(this.markerClassName).empty();
+       },
+
+       /* Enable the date picker to a jQuery selection.
+          @param  target    element - the target input field or division or span */
+       _enableDatepicker: function(target) {
+               var $target = $(target);
+               var inst = $.data(target, PROP_NAME);
+               if (!$target.hasClass(this.markerClassName)) {
+                       return;
+               }
+               var nodeName = target.nodeName.toLowerCase();
+               if (nodeName == 'input') {
+                       target.disabled = false;
+                       inst.trigger.filter('button').
+                               each(function() { this.disabled = false; }).end().
+                               filter('img').css({opacity: '1.0', cursor: ''});
+               }
+               else if (nodeName == 'div' || nodeName == 'span') {
+                       var inline = $target.children('.' + this._inlineClass);
+                       inline.children().removeClass('ui-state-disabled');
+               }
+               this._disabledInputs = $.map(this._disabledInputs,
+                       function(value) { return (value == target ? null : value); }); // delete entry
+       },
+
+       /* Disable the date picker to a jQuery selection.
+          @param  target    element - the target input field or division or span */
+       _disableDatepicker: function(target) {
+               var $target = $(target);
+               var inst = $.data(target, PROP_NAME);
+               if (!$target.hasClass(this.markerClassName)) {
+                       return;
+               }
+               var nodeName = target.nodeName.toLowerCase();
+               if (nodeName == 'input') {
+                       target.disabled = true;
+                       inst.trigger.filter('button').
+                               each(function() { this.disabled = true; }).end().
+                               filter('img').css({opacity: '0.5', cursor: 'default'});
+               }
+               else if (nodeName == 'div' || nodeName == 'span') {
+                       var inline = $target.children('.' + this._inlineClass);
+                       inline.children().addClass('ui-state-disabled');
+               }
+               this._disabledInputs = $.map(this._disabledInputs,
+                       function(value) { return (value == target ? null : value); }); // delete entry
+               this._disabledInputs[this._disabledInputs.length] = target;
+       },
+
+       /* Is the first field in a jQuery collection disabled as a datepicker?
+          @param  target    element - the target input field or division or span
+          @return boolean - true if disabled, false if enabled */
+       _isDisabledDatepicker: function(target) {
+               if (!target) {
+                       return false;
+               }
+               for (var i = 0; i < this._disabledInputs.length; i++) {
+                       if (this._disabledInputs[i] == target)
+                               return true;
+               }
+               return false;
+       },
+
+       /* Retrieve the instance data for the target control.
+          @param  target  element - the target input field or division or span
+          @return  object - the associated instance data
+          @throws  error if a jQuery problem getting data */
+       _getInst: function(target) {
+               try {
+                       return $.data(target, PROP_NAME);
+               }
+               catch (err) {
+                       throw 'Missing instance data for this datepicker';
+               }
+       },
+
+       /* Update or retrieve the settings for a date picker attached to an input field or division.
+          @param  target  element - the target input field or division or span
+          @param  name    object - the new settings to update or
+                          string - the name of the setting to change or retrieve,
+                          when retrieving also 'all' for all instance settings or
+                          'defaults' for all global defaults
+          @param  value   any - the new value for the setting
+                          (omit if above is an object or to retrieve a value) */
+       _optionDatepicker: function(target, name, value) {
+               var inst = this._getInst(target);
+               if (arguments.length == 2 && typeof name == 'string') {
+                       return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
+                               (inst ? (name == 'all' ? $.extend({}, inst.settings) :
+                               this._get(inst, name)) : null));
+               }
+               var settings = name || {};
+               if (typeof name == 'string') {
+                       settings = {};
+                       settings[name] = value;
+               }
+               if (inst) {
+                       if (this._curInst == inst) {
+                               this._hideDatepicker();
+                       }
+                       var date = this._getDateDatepicker(target, true);
+                       var minDate = this._getMinMaxDate(inst, 'min');
+                       var maxDate = this._getMinMaxDate(inst, 'max');
+                       extendRemove(inst.settings, settings);
+                       // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
+                       if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
+                               inst.settings.minDate = this._formatDate(inst, minDate);
+                       if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
+                               inst.settings.maxDate = this._formatDate(inst, maxDate);
+                       this._attachments($(target), inst);
+                       this._autoSize(inst);
+                       this._setDateDatepicker(target, date);
+                       this._updateDatepicker(inst);
+               }
+       },
+
+       // change method deprecated
+       _changeDatepicker: function(target, name, value) {
+               this._optionDatepicker(target, name, value);
+       },
+
+       /* Redraw the date picker attached to an input field or division.
+          @param  target  element - the target input field or division or span */
+       _refreshDatepicker: function(target) {
+               var inst = this._getInst(target);
+               if (inst) {
+                       this._updateDatepicker(inst);
+               }
+       },
+
+       /* Set the dates for a jQuery selection.
+          @param  target   element - the target input field or division or span
+          @param  date     Date - the new date */
+       _setDateDatepicker: function(target, date) {
+               var inst = this._getInst(target);
+               if (inst) {
+                       this._setDate(inst, date);
+                       this._updateDatepicker(inst);
+                       this._updateAlternate(inst);
+               }
+       },
+
+       /* Get the date(s) for the first entry in a jQuery selection.
+          @param  target     element - the target input field or division or span
+          @param  noDefault  boolean - true if no default date is to be used
+          @return Date - the current date */
+       _getDateDatepicker: function(target, noDefault) {
+               var inst = this._getInst(target);
+               if (inst && !inst.inline)
+                       this._setDateFromField(inst, noDefault);
+               return (inst ? this._getDate(inst) : null);
+       },
+
+       /* Handle keystrokes. */
+       _doKeyDown: function(event) {
+               var inst = $.datepicker._getInst(event.target);
+               var handled = true;
+               var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
+               inst._keyEvent = true;
+               if ($.datepicker._datepickerShowing)
+                       switch (event.keyCode) {
+                               case 9: $.datepicker._hideDatepicker();
+                                               handled = false;
+                                               break; // hide on tab out
+                               case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 
+                                                                       $.datepicker._currentClass + ')', inst.dpDiv);
+                                               if (sel[0])
+                                                       $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
+                                               else
+                                                       $.datepicker._hideDatepicker();
+                                               return false; // don't submit the form
+                                               break; // select the value on enter
+                               case 27: $.datepicker._hideDatepicker();
+                                               break; // hide on escape
+                               case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                       -$.datepicker._get(inst, 'stepBigMonths') :
+                                                       -$.datepicker._get(inst, 'stepMonths')), 'M');
+                                               break; // previous month/year on page up/+ ctrl
+                               case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                       +$.datepicker._get(inst, 'stepBigMonths') :
+                                                       +$.datepicker._get(inst, 'stepMonths')), 'M');
+                                               break; // next month/year on page down/+ ctrl
+                               case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // clear on ctrl or command +end
+                               case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // current on ctrl or command +home
+                               case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
+                                               handled = event.ctrlKey || event.metaKey;
+                                               // -1 day on ctrl or command +left
+                                               if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                                       -$.datepicker._get(inst, 'stepBigMonths') :
+                                                                       -$.datepicker._get(inst, 'stepMonths')), 'M');
+                                               // next month/year on alt +left on Mac
+                                               break;
+                               case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // -1 week on ctrl or command +up
+                               case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
+                                               handled = event.ctrlKey || event.metaKey;
+                                               // +1 day on ctrl or command +right
+                                               if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                                       +$.datepicker._get(inst, 'stepBigMonths') :
+                                                                       +$.datepicker._get(inst, 'stepMonths')), 'M');
+                                               // next month/year on alt +right
+                                               break;
+                               case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // +1 week on ctrl or command +down
+                               default: handled = false;
+                       }
+               else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
+                       $.datepicker._showDatepicker(this);
+               else {
+                       handled = false;
+               }
+               if (handled) {
+                       event.preventDefault();
+                       event.stopPropagation();
+               }
+       },
+
+       /* Filter entered characters - based on date format. */
+       _doKeyPress: function(event) {
+               var inst = $.datepicker._getInst(event.target);
+               if ($.datepicker._get(inst, 'constrainInput')) {
+                       var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
+                       var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
+                       return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
+               }
+       },
+
+       /* Synchronise manual entry and field/alternate field. */
+       _doKeyUp: function(event) {
+               var inst = $.datepicker._getInst(event.target);
+               if (inst.input.val() != inst.lastVal) {
+                       try {
+                               var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
+                                       (inst.input ? inst.input.val() : null),
+                                       $.datepicker._getFormatConfig(inst));
+                               if (date) { // only if valid
+                                       $.datepicker._setDateFromField(inst);
+                                       $.datepicker._updateAlternate(inst);
+                                       $.datepicker._updateDatepicker(inst);
+                               }
+                       }
+                       catch (event) {
+                               $.datepicker.log(event);
+                       }
+               }
+               return true;
+       },
+
+       /* Pop-up the date picker for a given input field.
+          @param  input  element - the input field attached to the date picker or
+                         event - if triggered by focus */
+       _showDatepicker: function(input) {
+               input = input.target || input;
+               if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
+                       input = $('input', input.parentNode)[0];
+               if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
+                       return;
+               var inst = $.datepicker._getInst(input);
+               if ($.datepicker._curInst && $.datepicker._curInst != inst) {
+                       $.datepicker._curInst.dpDiv.stop(true, true);
+               }
+               var beforeShow = $.datepicker._get(inst, 'beforeShow');
+               extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
+               inst.lastVal = null;
+               $.datepicker._lastInput = input;
+               $.datepicker._setDateFromField(inst);
+               if ($.datepicker._inDialog) // hide cursor
+                       input.value = '';
+               if (!$.datepicker._pos) { // position below input
+                       $.datepicker._pos = $.datepicker._findPos(input);
+                       $.datepicker._pos[1] += input.offsetHeight; // add the height
+               }
+               var isFixed = false;
+               $(input).parents().each(function() {
+                       isFixed |= $(this).css('position') == 'fixed';
+                       return !isFixed;
+               });
+               if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
+                       $.datepicker._pos[0] -= document.documentElement.scrollLeft;
+                       $.datepicker._pos[1] -= document.documentElement.scrollTop;
+               }
+               var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
+               $.datepicker._pos = null;
+               //to avoid flashes on Firefox
+               inst.dpDiv.empty();
+               // determine sizing offscreen
+               inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
+               $.datepicker._updateDatepicker(inst);
+               // fix width for dynamic number of date pickers
+               // and adjust position before showing
+               offset = $.datepicker._checkOffset(inst, offset, isFixed);
+               inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
+                       'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
+                       left: offset.left + 'px', top: offset.top + 'px'});
+               if (!inst.inline) {
+                       var showAnim = $.datepicker._get(inst, 'showAnim');
+                       var duration = $.datepicker._get(inst, 'duration');
+                       var postProcess = function() {
+                               $.datepicker._datepickerShowing = true;
+                               var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
+                               if( !! cover.length ){
+                                       var borders = $.datepicker._getBorders(inst.dpDiv);
+                                       cover.css({left: -borders[0], top: -borders[1],
+                                               width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
+                               }
+                       };
+                       inst.dpDiv.zIndex($(input).zIndex()+1);
+                       if ($.effects && $.effects[showAnim])
+                               inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
+                       else
+                               inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
+                       if (!showAnim || !duration)
+                               postProcess();
+                       if (inst.input.is(':visible') && !inst.input.is(':disabled'))
+                               inst.input.focus();
+                       $.datepicker._curInst = inst;
+               }
+       },
+
+       /* Generate the date picker content. */
+       _updateDatepicker: function(inst) {
+               var self = this;
+               var borders = $.datepicker._getBorders(inst.dpDiv);
+               inst.dpDiv.empty().append(this._generateHTML(inst));
+               var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
+               if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
+                       cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
+               }
+               inst.dpDiv.find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a')
+                               .bind('mouseout', function(){
+                                       $(this).removeClass('ui-state-hover');
+                                       if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
+                                       if(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
+                               })
+                               .bind('mouseover', function(){
+                                       if (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) {
+                                               $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
+                                               $(this).addClass('ui-state-hover');
+                                               if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
+                                               if(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
+                                       }
+                               })
+                       .end()
+                       .find('.' + this._dayOverClass + ' a')
+                               .trigger('mouseover')
+                       .end();
+               var numMonths = this._getNumberOfMonths(inst);
+               var cols = numMonths[1];
+               var width = 17;
+               if (cols > 1)
+                       inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
+               else
+                       inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
+               inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
+                       'Class']('ui-datepicker-multi');
+               inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
+                       'Class']('ui-datepicker-rtl');
+               if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
+                               // #6694 - don't focus the input if it's already focused
+                               // this breaks the change event in IE
+                               inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
+                       inst.input.focus();
+               // deffered render of the years select (to avoid flashes on Firefox) 
+               if( inst.yearshtml ){
+                       var origyearshtml = inst.yearshtml;
+                       setTimeout(function(){
+                               //assure that inst.yearshtml didn't change.
+                               if( origyearshtml === inst.yearshtml ){
+                                       inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
+                               }
+                               origyearshtml = inst.yearshtml = null;
+                       }, 0);
+               }
+       },
+
+       /* Retrieve the size of left and top borders for an element.
+          @param  elem  (jQuery object) the element of interest
+          @return  (number[2]) the left and top borders */
+       _getBorders: function(elem) {
+               var convert = function(value) {
+                       return {thin: 1, medium: 2, thick: 3}[value] || value;
+               };
+               return [parseFloat(convert(elem.css('border-left-width'))),
+                       parseFloat(convert(elem.css('border-top-width')))];
+       },
+
+       /* Check positioning to remain on screen. */
+       _checkOffset: function(inst, offset, isFixed) {
+               var dpWidth = inst.dpDiv.outerWidth();
+               var dpHeight = inst.dpDiv.outerHeight();
+               var inputWidth = inst.input ? inst.input.outerWidth() : 0;
+               var inputHeight = inst.input ? inst.input.outerHeight() : 0;
+               var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
+               var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
+
+               offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
+               offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
+               offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
+
+               // now check if datepicker is showing outside window viewport - move to a better place if so.
+               offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
+                       Math.abs(offset.left + dpWidth - viewWidth) : 0);
+               offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
+                       Math.abs(dpHeight + inputHeight) : 0);
+
+               return offset;
+       },
+
+       /* Find an object's position on the screen. */
+       _findPos: function(obj) {
+               var inst = this._getInst(obj);
+               var isRTL = this._get(inst, 'isRTL');
+        while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
+            obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
+        }
+        var position = $(obj).offset();
+           return [position.left, position.top];
+       },
+
+       /* Hide the date picker from view.
+          @param  input  element - the input field attached to the date picker */
+       _hideDatepicker: function(input) {
+               var inst = this._curInst;
+               if (!inst || (input && inst != $.data(input, PROP_NAME)))
+                       return;
+               if (this._datepickerShowing) {
+                       var showAnim = this._get(inst, 'showAnim');
+                       var duration = this._get(inst, 'duration');
+                       var postProcess = function() {
+                               $.datepicker._tidyDialog(inst);
+                               this._curInst = null;
+                       };
+                       if ($.effects && $.effects[showAnim])
+                               inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
+                       else
+                               inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
+                                       (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
+                       if (!showAnim)
+                               postProcess();
+                       var onClose = this._get(inst, 'onClose');
+                       if (onClose)
+                               onClose.apply((inst.input ? inst.input[0] : null),
+                                       [(inst.input ? inst.input.val() : ''), inst]);  // trigger custom callback
+                       this._datepickerShowing = false;
+                       this._lastInput = null;
+                       if (this._inDialog) {
+                               this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
+                               if ($.blockUI) {
+                                       $.unblockUI();
+                                       $('body').append(this.dpDiv);
+                               }
+                       }
+                       this._inDialog = false;
+               }
+       },
+
+       /* Tidy up after a dialog display. */
+       _tidyDialog: function(inst) {
+               inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
+       },
+
+       /* Close date picker if clicked elsewhere. */
+       _checkExternalClick: function(event) {
+               if (!$.datepicker._curInst)
+                       return;
+               var $target = $(event.target);
+               if ($target[0].id != $.datepicker._mainDivId &&
+                               $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
+                               !$target.hasClass($.datepicker.markerClassName) &&
+                               !$target.hasClass($.datepicker._triggerClass) &&
+                               $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
+                       $.datepicker._hideDatepicker();
+       },
+
+       /* Adjust one of the date sub-fields. */
+       _adjustDate: function(id, offset, period) {
+               var target = $(id);
+               var inst = this._getInst(target[0]);
+               if (this._isDisabledDatepicker(target[0])) {
+                       return;
+               }
+               this._adjustInstDate(inst, offset +
+                       (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
+                       period);
+               this._updateDatepicker(inst);
+       },
+
+       /* Action for current link. */
+       _gotoToday: function(id) {
+               var target = $(id);
+               var inst = this._getInst(target[0]);
+               if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
+                       inst.selectedDay = inst.currentDay;
+                       inst.drawMonth = inst.selectedMonth = inst.currentMonth;
+                       inst.drawYear = inst.selectedYear = inst.currentYear;
+               }
+               else {
+                       var date = new Date();
+                       inst.selectedDay = date.getDate();
+                       inst.drawMonth = inst.selectedMonth = date.getMonth();
+                       inst.drawYear = inst.selectedYear = date.getFullYear();
+               }
+               this._notifyChange(inst);
+               this._adjustDate(target);
+       },
+
+       /* Action for selecting a new month/year. */
+       _selectMonthYear: function(id, select, period) {
+               var target = $(id);
+               var inst = this._getInst(target[0]);
+               inst._selectingMonthYear = false;
+               inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
+               inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
+                       parseInt(select.options[select.selectedIndex].value,10);
+               this._notifyChange(inst);
+               this._adjustDate(target);
+       },
+
+       /* Restore input focus after not changing month/year. */
+       _clickMonthYear: function(id) {
+               var target = $(id);
+               var inst = this._getInst(target[0]);
+               if (inst.input && inst._selectingMonthYear) {
+                       setTimeout(function() {
+                               inst.input.focus();
+                       }, 0);
+               }
+               inst._selectingMonthYear = !inst._selectingMonthYear;
+       },
+
+       /* Action for selecting a day. */
+       _selectDay: function(id, month, year, td) {
+               var target = $(id);
+               if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
+                       return;
+               }
+               var inst = this._getInst(target[0]);
+               inst.selectedDay = inst.currentDay = $('a', td).html();
+               inst.selectedMonth = inst.currentMonth = month;
+               inst.selectedYear = inst.currentYear = year;
+               this._selectDate(id, this._formatDate(inst,
+                       inst.currentDay, inst.currentMonth, inst.currentYear));
+       },
+
+       /* Erase the input field and hide the date picker. */
+       _clearDate: function(id) {
+               var target = $(id);
+               var inst = this._getInst(target[0]);
+               this._selectDate(target, '');
+       },
+
+       /* Update the input field with the selected date. */
+       _selectDate: function(id, dateStr) {
+               var target = $(id);
+               var inst = this._getInst(target[0]);
+               dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
+               if (inst.input)
+                       inst.input.val(dateStr);
+               this._updateAlternate(inst);
+               var onSelect = this._get(inst, 'onSelect');
+               if (onSelect)
+                       onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
+               else if (inst.input)
+                       inst.input.trigger('change'); // fire the change event
+               if (inst.inline)
+                       this._updateDatepicker(inst);
+               else {
+                       this._hideDatepicker();
+                       this._lastInput = inst.input[0];
+                       if (typeof(inst.input[0]) != 'object')
+                               inst.input.focus(); // restore focus
+                       this._lastInput = null;
+               }
+       },
+
+       /* Update any alternate field to synchronise with the main field. */
+       _updateAlternate: function(inst) {
+               var altField = this._get(inst, 'altField');
+               if (altField) { // update alternate field too
+                       var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
+                       var date = this._getDate(inst);
+                       var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
+                       $(altField).each(function() { $(this).val(dateStr); });
+               }
+       },
+
+       /* Set as beforeShowDay function to prevent selection of weekends.
+          @param  date  Date - the date to customise
+          @return [boolean, string] - is this date selectable?, what is its CSS class? */
+       noWeekends: function(date) {
+               var day = date.getDay();
+               return [(day > 0 && day < 6), ''];
+       },
+
+       /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
+          @param  date  Date - the date to get the week for
+          @return  number - the number of the week within the year that contains this date */
+       iso8601Week: function(date) {
+               var checkDate = new Date(date.getTime());
+               // Find Thursday of this week starting on Monday
+               checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
+               var time = checkDate.getTime();
+               checkDate.setMonth(0); // Compare with Jan 1
+               checkDate.setDate(1);
+               return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
+       },
+
+       /* Parse a string value into a date object.
+          See formatDate below for the possible formats.
+
+          @param  format    string - the expected format of the date
+          @param  value     string - the date in the above format
+          @param  settings  Object - attributes include:
+                            shortYearCutoff  number - the cutoff year for determining the century (optional)
+                            dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
+                            dayNames         string[7] - names of the days from Sunday (optional)
+                            monthNamesShort  string[12] - abbreviated names of the months (optional)
+                            monthNames       string[12] - names of the months (optional)
+          @return  Date - the extracted date value or null if value is blank */
+       parseDate: function (format, value, settings) {
+               if (format == null || value == null)
+                       throw 'Invalid arguments';
+               value = (typeof value == 'object' ? value.toString() : value + '');
+               if (value == '')
+                       return null;
+               var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
+               shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
+                               new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
+               var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
+               var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
+               var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
+               var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
+               var year = -1;
+               var month = -1;
+               var day = -1;
+               var doy = -1;
+               var literal = false;
+               // Check whether a format character is doubled
+               var lookAhead = function(match) {
+                       var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
+                       if (matches)
+                               iFormat++;
+                       return matches;
+               };
+               // Extract a number from the string value
+               var getNumber = function(match) {
+                       var isDoubled = lookAhead(match);
+                       var size = (match == '@' ? 14 : (match == '!' ? 20 :
+                               (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
+                       var digits = new RegExp('^\\d{1,' + size + '}');
+                       var num = value.substring(iValue).match(digits);
+                       if (!num)
+                               throw 'Missing number at position ' + iValue;
+                       iValue += num[0].length;
+                       return parseInt(num[0], 10);
+               };
+               // Extract a name from the string value and convert to an index
+               var getName = function(match, shortNames, longNames) {
+                       var names = (lookAhead(match) ? longNames : shortNames);
+                       for (var i = 0; i < names.length; i++) {
+                               if (value.substr(iValue, names[i].length).toLowerCase() == names[i].toLowerCase()) {
+                                       iValue += names[i].length;
+                                       return i + 1;
+                               }
+                       }
+                       throw 'Unknown name at position ' + iValue;
+               };
+               // Confirm that a literal character matches the string value
+               var checkLiteral = function() {
+                       if (value.charAt(iValue) != format.charAt(iFormat))
+                               throw 'Unexpected literal at position ' + iValue;
+                       iValue++;
+               };
+               var iValue = 0;
+               for (var iFormat = 0; iFormat < format.length; iFormat++) {
+                       if (literal)
+                               if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+                                       literal = false;
+                               else
+                                       checkLiteral();
+                       else
+                               switch (format.charAt(iFormat)) {
+                                       case 'd':
+                                               day = getNumber('d');
+                                               break;
+                                       case 'D':
+                                               getName('D', dayNamesShort, dayNames);
+                                               break;
+                                       case 'o':
+                                               doy = getNumber('o');
+                                               break;
+                                       case 'm':
+                                               month = getNumber('m');
+                                               break;
+                                       case 'M':
+                                               month = getName('M', monthNamesShort, monthNames);
+                                               break;
+                                       case 'y':
+                                               year = getNumber('y');
+                                               break;
+                                       case '@':
+                                               var date = new Date(getNumber('@'));
+                                               year = date.getFullYear();
+                                               month = date.getMonth() + 1;
+                                               day = date.getDate();
+                                               break;
+                                       case '!':
+                                               var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
+                                               year = date.getFullYear();
+                                               month = date.getMonth() + 1;
+                                               day = date.getDate();
+                                               break;
+                                       case "'":
+                                               if (lookAhead("'"))
+                                                       checkLiteral();
+                                               else
+                                                       literal = true;
+                                               break;
+                                       default:
+                                               checkLiteral();
+                               }
+               }
+               if (year == -1)
+                       year = new Date().getFullYear();
+               else if (year < 100)
+                       year += new Date().getFullYear() - new Date().getFullYear() % 100 +
+                               (year <= shortYearCutoff ? 0 : -100);
+               if (doy > -1) {
+                       month = 1;
+                       day = doy;
+                       do {
+                               var dim = this._getDaysInMonth(year, month - 1);
+                               if (day <= dim)
+                                       break;
+                               month++;
+                               day -= dim;
+                       } while (true);
+               }
+               var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
+               if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
+                       throw 'Invalid date'; // E.g. 31/02/00
+               return date;
+       },
+
+       /* Standard date formats. */
+       ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
+       COOKIE: 'D, dd M yy',
+       ISO_8601: 'yy-mm-dd',
+       RFC_822: 'D, d M y',
+       RFC_850: 'DD, dd-M-y',
+       RFC_1036: 'D, d M y',
+       RFC_1123: 'D, d M yy',
+       RFC_2822: 'D, d M yy',
+       RSS: 'D, d M y', // RFC 822
+       TICKS: '!',
+       TIMESTAMP: '@',
+       W3C: 'yy-mm-dd', // ISO 8601
+
+       _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
+               Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
+
+       /* Format a date object into a string value.
+          The format can be combinations of the following:
+          d  - day of month (no leading zero)
+          dd - day of month (two digit)
+          o  - day of year (no leading zeros)
+          oo - day of year (three digit)
+          D  - day name short
+          DD - day name long
+          m  - month of year (no leading zero)
+          mm - month of year (two digit)
+          M  - month name short
+          MM - month name long
+          y  - year (two digit)
+          yy - year (four digit)
+          @ - Unix timestamp (ms since 01/01/1970)
+          ! - Windows ticks (100ns since 01/01/0001)
+          '...' - literal text
+          '' - single quote
+
+          @param  format    string - the desired format of the date
+          @param  date      Date - the date value to format
+          @param  settings  Object - attributes include:
+                            dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
+                            dayNames         string[7] - names of the days from Sunday (optional)
+                            monthNamesShort  string[12] - abbreviated names of the months (optional)
+                            monthNames       string[12] - names of the months (optional)
+          @return  string - the date in the above format */
+       formatDate: function (format, date, settings) {
+               if (!date)
+                       return '';
+               var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
+               var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
+               var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
+               var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
+               // Check whether a format character is doubled
+               var lookAhead = function(match) {
+                       var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
+                       if (matches)
+                               iFormat++;
+                       return matches;
+               };
+               // Format a number, with leading zero if necessary
+               var formatNumber = function(match, value, len) {
+                       var num = '' + value;
+                       if (lookAhead(match))
+                               while (num.length < len)
+                                       num = '0' + num;
+                       return num;
+               };
+               // Format a name, short or long as requested
+               var formatName = function(match, value, shortNames, longNames) {
+                       return (lookAhead(match) ? longNames[value] : shortNames[value]);
+               };
+               var output = '';
+               var literal = false;
+               if (date)
+                       for (var iFormat = 0; iFormat < format.length; iFormat++) {
+                               if (literal)
+                                       if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+                                               literal = false;
+                                       else
+                                               output += format.charAt(iFormat);
+                               else
+                                       switch (format.charAt(iFormat)) {
+                                               case 'd':
+                                                       output += formatNumber('d', date.getDate(), 2);
+                                                       break;
+                                               case 'D':
+                                                       output += formatName('D', date.getDay(), dayNamesShort, dayNames);
+                                                       break;
+                                               case 'o':
+                                                       output += formatNumber('o',
+                                                               (date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3);
+                                                       break;
+                                               case 'm':
+                                                       output += formatNumber('m', date.getMonth() + 1, 2);
+                                                       break;
+                                               case 'M':
+                                                       output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
+                                                       break;
+                                               case 'y':
+                                                       output += (lookAhead('y') ? date.getFullYear() :
+                                                               (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
+                                                       break;
+                                               case '@':
+                                                       output += date.getTime();
+                                                       break;
+                                               case '!':
+                                                       output += date.getTime() * 10000 + this._ticksTo1970;
+                                                       break;
+                                               case "'":
+                                                       if (lookAhead("'"))
+                                                               output += "'";
+                                                       else
+                                                               literal = true;
+                                                       break;
+                                               default:
+                                                       output += format.charAt(iFormat);
+                                       }
+                       }
+               return output;
+       },
+
+       /* Extract all possible characters from the date format. */
+       _possibleChars: function (format) {
+               var chars = '';
+               var literal = false;
+               // Check whether a format character is doubled
+               var lookAhead = function(match) {
+                       var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
+                       if (matches)
+                               iFormat++;
+                       return matches;
+               };
+               for (var iFormat = 0; iFormat < format.length; iFormat++)
+                       if (literal)
+                               if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+                                       literal = false;
+                               else
+                                       chars += format.charAt(iFormat);
+                       else
+                               switch (format.charAt(iFormat)) {
+                                       case 'd': case 'm': case 'y': case '@':
+                                               chars += '0123456789';
+                                               break;
+                                       case 'D': case 'M':
+                                               return null; // Accept anything
+                                       case "'":
+                                               if (lookAhead("'"))
+                                                       chars += "'";
+                                               else
+                                                       literal = true;
+                                               break;
+                                       default:
+                                               chars += format.charAt(iFormat);
+                               }
+               return chars;
+       },
+
+       /* Get a setting value, defaulting if necessary. */
+       _get: function(inst, name) {
+               return inst.settings[name] !== undefined ?
+                       inst.settings[name] : this._defaults[name];
+       },
+
+       /* Parse existing date and initialise date picker. */
+       _setDateFromField: function(inst, noDefault) {
+               if (inst.input.val() == inst.lastVal) {
+                       return;
+               }
+               var dateFormat = this._get(inst, 'dateFormat');
+               var dates = inst.lastVal = inst.input ? inst.input.val() : null;
+               var date, defaultDate;
+               date = defaultDate = this._getDefaultDate(inst);
+               var settings = this._getFormatConfig(inst);
+               try {
+                       date = this.parseDate(dateFormat, dates, settings) || defaultDate;
+               } catch (event) {
+                       this.log(event);
+                       dates = (noDefault ? '' : dates);
+               }
+               inst.selectedDay = date.getDate();
+               inst.drawMonth = inst.selectedMonth = date.getMonth();
+               inst.drawYear = inst.selectedYear = date.getFullYear();
+               inst.currentDay = (dates ? date.getDate() : 0);
+               inst.currentMonth = (dates ? date.getMonth() : 0);
+               inst.currentYear = (dates ? date.getFullYear() : 0);
+               this._adjustInstDate(inst);
+       },
+
+       /* Retrieve the default date shown on opening. */
+       _getDefaultDate: function(inst) {
+               return this._restrictMinMax(inst,
+                       this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
+       },
+
+       /* A date may be specified as an exact value or a relative one. */
+       _determineDate: function(inst, date, defaultDate) {
+               var offsetNumeric = function(offset) {
+                       var date = new Date();
+                       date.setDate(date.getDate() + offset);
+                       return date;
+               };
+               var offsetString = function(offset) {
+                       try {
+                               return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
+                                       offset, $.datepicker._getFormatConfig(inst));
+                       }
+                       catch (e) {
+                               // Ignore
+                       }
+                       var date = (offset.toLowerCase().match(/^c/) ?
+                               $.datepicker._getDate(inst) : null) || new Date();
+                       var year = date.getFullYear();
+                       var month = date.getMonth();
+                       var day = date.getDate();
+                       var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
+                       var matches = pattern.exec(offset);
+                       while (matches) {
+                               switch (matches[2] || 'd') {
+                                       case 'd' : case 'D' :
+                                               day += parseInt(matches[1],10); break;
+                                       case 'w' : case 'W' :
+                                               day += parseInt(matches[1],10) * 7; break;
+                                       case 'm' : case 'M' :
+                                               month += parseInt(matches[1],10);
+                                               day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
+                                               break;
+                                       case 'y': case 'Y' :
+                                               year += parseInt(matches[1],10);
+                                               day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
+                                               break;
+                               }
+                               matches = pattern.exec(offset);
+                       }
+                       return new Date(year, month, day);
+               };
+               var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
+                       (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
+               newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
+               if (newDate) {
+                       newDate.setHours(0);
+                       newDate.setMinutes(0);
+                       newDate.setSeconds(0);
+                       newDate.setMilliseconds(0);
+               }
+               return this._daylightSavingAdjust(newDate);
+       },
+
+       /* Handle switch to/from daylight saving.
+          Hours may be non-zero on daylight saving cut-over:
+          > 12 when midnight changeover, but then cannot generate
+          midnight datetime, so jump to 1AM, otherwise reset.
+          @param  date  (Date) the date to check
+          @return  (Date) the corrected date */
+       _daylightSavingAdjust: function(date) {
+               if (!date) return null;
+               date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
+               return date;
+       },
+
+       /* Set the date(s) directly. */
+       _setDate: function(inst, date, noChange) {
+               var clear = !date;
+               var origMonth = inst.selectedMonth;
+               var origYear = inst.selectedYear;
+               var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
+               inst.selectedDay = inst.currentDay = newDate.getDate();
+               inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
+               inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
+               if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
+                       this._notifyChange(inst);
+               this._adjustInstDate(inst);
+               if (inst.input) {
+                       inst.input.val(clear ? '' : this._formatDate(inst));
+               }
+       },
+
+       /* Retrieve the date(s) directly. */
+       _getDate: function(inst) {
+               var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
+                       this._daylightSavingAdjust(new Date(
+                       inst.currentYear, inst.currentMonth, inst.currentDay)));
+                       return startDate;
+       },
+
+       /* Generate the HTML for the current state of the date picker. */
+       _generateHTML: function(inst) {
+               var today = new Date();
+               today = this._daylightSavingAdjust(
+                       new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
+               var isRTL = this._get(inst, 'isRTL');
+               var showButtonPanel = this._get(inst, 'showButtonPanel');
+               var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
+               var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
+               var numMonths = this._getNumberOfMonths(inst);
+               var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
+               var stepMonths = this._get(inst, 'stepMonths');
+               var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
+               var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
+                       new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
+               var minDate = this._getMinMaxDate(inst, 'min');
+               var maxDate = this._getMinMaxDate(inst, 'max');
+               var drawMonth = inst.drawMonth - showCurrentAtPos;
+               var drawYear = inst.drawYear;
+               if (drawMonth < 0) {
+                       drawMonth += 12;
+                       drawYear--;
+               }
+               if (maxDate) {
+                       var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
+                               maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
+                       maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
+                       while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
+                               drawMonth--;
+                               if (drawMonth < 0) {
+                                       drawMonth = 11;
+                                       drawYear--;
+                               }
+                       }
+               }
+               inst.drawMonth = drawMonth;
+               inst.drawYear = drawYear;
+               var prevText = this._get(inst, 'prevText');
+               prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
+                       this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
+                       this._getFormatConfig(inst)));
+               var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
+                       '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+                       '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
+                       ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
+                       (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
+               var nextText = this._get(inst, 'nextText');
+               nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
+                       this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
+                       this._getFormatConfig(inst)));
+               var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
+                       '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+                       '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
+                       ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
+                       (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
+               var currentText = this._get(inst, 'currentText');
+               var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
+               currentText = (!navigationAsDateFormat ? currentText :
+                       this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
+               var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+                       '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
+               var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
+                       (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+                       '.datepicker._gotoToday(\'#' + inst.id + '\');"' +
+                       '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
+               var firstDay = parseInt(this._get(inst, 'firstDay'),10);
+               firstDay = (isNaN(firstDay) ? 0 : firstDay);
+               var showWeek = this._get(inst, 'showWeek');
+               var dayNames = this._get(inst, 'dayNames');
+               var dayNamesShort = this._get(inst, 'dayNamesShort');
+               var dayNamesMin = this._get(inst, 'dayNamesMin');
+               var monthNames = this._get(inst, 'monthNames');
+               var monthNamesShort = this._get(inst, 'monthNamesShort');
+               var beforeShowDay = this._get(inst, 'beforeShowDay');
+               var showOtherMonths = this._get(inst, 'showOtherMonths');
+               var selectOtherMonths = this._get(inst, 'selectOtherMonths');
+               var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
+               var defaultDate = this._getDefaultDate(inst);
+               var html = '';
+               for (var row = 0; row < numMonths[0]; row++) {
+                       var group = '';
+                       for (var col = 0; col < numMonths[1]; col++) {
+                               var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
+                               var cornerClass = ' ui-corner-all';
+                               var calender = '';
+                               if (isMultiMonth) {
+                                       calender += '<div class="ui-datepicker-group';
+                                       if (numMonths[1] > 1)
+                                               switch (col) {
+                                                       case 0: calender += ' ui-datepicker-group-first';
+                                                               cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
+                                                       case numMonths[1]-1: calender += ' ui-datepicker-group-last';
+                                                               cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
+                                                       default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
+                                               }
+                                       calender += '">';
+                               }
+                               calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
+                                       (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
+                                       (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
+                                       this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
+                                       row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
+                                       '</div><table class="ui-datepicker-calendar"><thead>' +
+                                       '<tr>';
+                               var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
+                               for (var dow = 0; dow < 7; dow++) { // days of the week
+                                       var day = (dow + firstDay) % 7;
+                                       thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
+                                               '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
+                               }
+                               calender += thead + '</tr></thead><tbody>';
+                               var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
+                               if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
+                                       inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
+                               var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
+                               var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
+                               var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
+                               for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
+                                       calender += '<tr>';
+                                       var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
+                                               this._get(inst, 'calculateWeek')(printDate) + '</td>');
+                                       for (var dow = 0; dow < 7; dow++) { // create date picker days
+                                               var daySettings = (beforeShowDay ?
+                                                       beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
+                                               var otherMonth = (printDate.getMonth() != drawMonth);
+                                               var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
+                                                       (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
+                                               tbody += '<td class="' +
+                                                       ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
+                                                       (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
+                                                       ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
+                                                       (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
+                                                       // or defaultDate is current printedDate and defaultDate is selectedDate
+                                                       ' ' + this._dayOverClass : '') + // highlight selected day
+                                                       (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
+                                                       (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
+                                                       (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
+                                                       (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
+                                                       ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
+                                                       (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
+                                                       inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
+                                                       (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
+                                                       (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
+                                                       (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
+                                                       (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
+                                                       (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
+                                                       '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
+                                               printDate.setDate(printDate.getDate() + 1);
+                                               printDate = this._daylightSavingAdjust(printDate);
+                                       }
+                                       calender += tbody + '</tr>';
+                               }
+                               drawMonth++;
+                               if (drawMonth > 11) {
+                                       drawMonth = 0;
+                                       drawYear++;
+                               }
+                               calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 
+                                                       ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
+                               group += calender;
+                       }
+                       html += group;
+               }
+               html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
+                       '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
+               inst._keyEvent = false;
+               return html;
+       },
+
+       /* Generate the month and year header. */
+       _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
+                       secondary, monthNames, monthNamesShort) {
+               var changeMonth = this._get(inst, 'changeMonth');
+               var changeYear = this._get(inst, 'changeYear');
+               var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
+               var html = '<div class="ui-datepicker-title">';
+               var monthHtml = '';
+               // month selection
+               if (secondary || !changeMonth)
+                       monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
+               else {
+                       var inMinYear = (minDate && minDate.getFullYear() == drawYear);
+                       var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
+                       monthHtml += '<select class="ui-datepicker-month" ' +
+                               'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
+                               'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
+                               '>';
+                       for (var month = 0; month < 12; month++) {
+                               if ((!inMinYear || month >= minDate.getMonth()) &&
+                                               (!inMaxYear || month <= maxDate.getMonth()))
+                                       monthHtml += '<option value="' + month + '"' +
+                                               (month == drawMonth ? ' selected="selected"' : '') +
+                                               '>' + monthNamesShort[month] + '</option>';
+                       }
+                       monthHtml += '</select>';
+               }
+               if (!showMonthAfterYear)
+                       html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
+               // year selection
+               if ( !inst.yearshtml ) {
+                       inst.yearshtml = '';
+                       if (secondary || !changeYear)
+                               html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
+                       else {
+                               // determine range of years to display
+                               var years = this._get(inst, 'yearRange').split(':');
+                               var thisYear = new Date().getFullYear();
+                               var determineYear = function(value) {
+                                       var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
+                                               (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
+                                               parseInt(value, 10)));
+                                       return (isNaN(year) ? thisYear : year);
+                               };
+                               var year = determineYear(years[0]);
+                               var endYear = Math.max(year, determineYear(years[1] || ''));
+                               year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
+                               endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
+                               inst.yearshtml += '<select class="ui-datepicker-year" ' +
+                                       'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
+                                       'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
+                                       '>';
+                               for (; year <= endYear; year++) {
+                                       inst.yearshtml += '<option value="' + year + '"' +
+                                               (year == drawYear ? ' selected="selected"' : '') +
+                                               '>' + year + '</option>';
+                               }
+                               inst.yearshtml += '</select>';
+                               //when showing there is no need for later update
+                               if( ! $.browser.mozilla ){
+                                       html += inst.yearshtml;
+                                       inst.yearshtml = null;
+                               } else {
+                                       // will be replaced later with inst.yearshtml
+                                       html += '<select class="ui-datepicker-year"><option value="' + drawYear + '" selected="selected">' + drawYear + '</option></select>';
+                               }
+                       }
+               }
+               html += this._get(inst, 'yearSuffix');
+               if (showMonthAfterYear)
+                       html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
+               html += '</div>'; // Close datepicker_header
+               return html;
+       },
+
+       /* Adjust one of the date sub-fields. */
+       _adjustInstDate: function(inst, offset, period) {
+               var year = inst.drawYear + (period == 'Y' ? offset : 0);
+               var month = inst.drawMonth + (period == 'M' ? offset : 0);
+               var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
+                       (period == 'D' ? offset : 0);
+               var date = this._restrictMinMax(inst,
+                       this._daylightSavingAdjust(new Date(year, month, day)));
+               inst.selectedDay = date.getDate();
+               inst.drawMonth = inst.selectedMonth = date.getMonth();
+               inst.drawYear = inst.selectedYear = date.getFullYear();
+               if (period == 'M' || period == 'Y')
+                       this._notifyChange(inst);
+       },
+
+       /* Ensure a date is within any min/max bounds. */
+       _restrictMinMax: function(inst, date) {
+               var minDate = this._getMinMaxDate(inst, 'min');
+               var maxDate = this._getMinMaxDate(inst, 'max');
+               var newDate = (minDate && date < minDate ? minDate : date);
+               newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
+               return newDate;
+       },
+
+       /* Notify change of month/year. */
+       _notifyChange: function(inst) {
+               var onChange = this._get(inst, 'onChangeMonthYear');
+               if (onChange)
+                       onChange.apply((inst.input ? inst.input[0] : null),
+                               [inst.selectedYear, inst.selectedMonth + 1, inst]);
+       },
+
+       /* Determine the number of months to show. */
+       _getNumberOfMonths: function(inst) {
+               var numMonths = this._get(inst, 'numberOfMonths');
+               return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
+       },
+
+       /* Determine the current maximum date - ensure no time components are set. */
+       _getMinMaxDate: function(inst, minMax) {
+               return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
+       },
+
+       /* Find the number of days in a given month. */
+       _getDaysInMonth: function(year, month) {
+               return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
+       },
+
+       /* Find the day of the week of the first of a month. */
+       _getFirstDayOfMonth: function(year, month) {
+               return new Date(year, month, 1).getDay();
+       },
+
+       /* Determines if we should allow a "next/prev" month display change. */
+       _canAdjustMonth: function(inst, offset, curYear, curMonth) {
+               var numMonths = this._getNumberOfMonths(inst);
+               var date = this._daylightSavingAdjust(new Date(curYear,
+                       curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
+               if (offset < 0)
+                       date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
+               return this._isInRange(inst, date);
+       },
+
+       /* Is the given date in the accepted range? */
+       _isInRange: function(inst, date) {
+               var minDate = this._getMinMaxDate(inst, 'min');
+               var maxDate = this._getMinMaxDate(inst, 'max');
+               return ((!minDate || date.getTime() >= minDate.getTime()) &&
+                       (!maxDate || date.getTime() <= maxDate.getTime()));
+       },
+
+       /* Provide the configuration settings for formatting/parsing. */
+       _getFormatConfig: function(inst) {
+               var shortYearCutoff = this._get(inst, 'shortYearCutoff');
+               shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
+                       new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
+               return {shortYearCutoff: shortYearCutoff,
+                       dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
+                       monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
+       },
+
+       /* Format the given date for display. */
+       _formatDate: function(inst, day, month, year) {
+               if (!day) {
+                       inst.currentDay = inst.selectedDay;
+                       inst.currentMonth = inst.selectedMonth;
+                       inst.currentYear = inst.selectedYear;
+               }
+               var date = (day ? (typeof day == 'object' ? day :
+                       this._daylightSavingAdjust(new Date(year, month, day))) :
+                       this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
+               return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
+       }
+});
+
+/* jQuery extend now ignores nulls! */
+function extendRemove(target, props) {
+       $.extend(target, props);
+       for (var name in props)
+               if (props[name] == null || props[name] == undefined)
+                       target[name] = props[name];
+       return target;
+};
+
+/* Determine whether an object is an array. */
+function isArray(a) {
+       return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
+               (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
+};
+
+/* Invoke the datepicker functionality.
+   @param  options  string - a command, optionally followed by additional parameters or
+                    Object - settings for attaching new datepicker functionality
+   @return  jQuery object */
+$.fn.datepicker = function(options){
+       
+       /* Verify an empty collection wasn't passed - Fixes #6976 */
+       if ( !this.length ) {
+               return this;
+       }
+       
+       /* Initialise the date picker. */
+       if (!$.datepicker.initialized) {
+               $(document).mousedown($.datepicker._checkExternalClick).
+                       find('body').append($.datepicker.dpDiv);
+               $.datepicker.initialized = true;
+       }
+
+       var otherArgs = Array.prototype.slice.call(arguments, 1);
+       if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
+               return $.datepicker['_' + options + 'Datepicker'].
+                       apply($.datepicker, [this[0]].concat(otherArgs));
+       if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
+               return $.datepicker['_' + options + 'Datepicker'].
+                       apply($.datepicker, [this[0]].concat(otherArgs));
+       return this.each(function() {
+               typeof options == 'string' ?
+                       $.datepicker['_' + options + 'Datepicker'].
+                               apply($.datepicker, [this].concat(otherArgs)) :
+                       $.datepicker._attachDatepicker(this, options);
+       });
+};
+
+$.datepicker = new Datepicker(); // singleton instance
+$.datepicker.initialized = false;
+$.datepicker.uuid = new Date().getTime();
+$.datepicker.version = "1.8.12";
+
+// Workaround for #4055
+// Add another global to avoid noConflict issues with inline event handlers
+window['DP_jQuery_' + dpuuid] = $;
+
+})(jQuery);
+/*
+ * jQuery UI Dialog 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.widget.js
+ *  jquery.ui.button.js
+ *     jquery.ui.draggable.js
+ *     jquery.ui.mouse.js
+ *     jquery.ui.position.js
+ *     jquery.ui.resizable.js
+ */
+(function( $, undefined ) {
+
+var uiDialogClasses =
+               'ui-dialog ' +
+               'ui-widget ' +
+               'ui-widget-content ' +
+               'ui-corner-all ',
+       sizeRelatedOptions = {
+               buttons: true,
+               height: true,
+               maxHeight: true,
+               maxWidth: true,
+               minHeight: true,
+               minWidth: true,
+               width: true
+       },
+       resizableRelatedOptions = {
+               maxHeight: true,
+               maxWidth: true,
+               minHeight: true,
+               minWidth: true
+       },
+       // support for jQuery 1.3.2 - handle common attrFn methods for dialog
+       attrFn = $.attrFn || {
+               val: true,
+               css: true,
+               html: true,
+               text: true,
+               data: true,
+               width: true,
+               height: true,
+               offset: true,
+               click: true
+       };
+
+$.widget("ui.dialog", {
+       options: {
+               autoOpen: true,
+               buttons: {},
+               closeOnEscape: true,
+               closeText: 'close',
+               dialogClass: '',
+               draggable: true,
+               hide: null,
+               height: 'auto',
+               maxHeight: false,
+               maxWidth: false,
+               minHeight: 150,
+               minWidth: 150,
+               modal: false,
+               position: {
+                       my: 'center',
+                       at: 'center',
+                       collision: 'fit',
+                       // ensure that the titlebar is never outside the document
+                       using: function(pos) {
+                               var topOffset = $(this).css(pos).offset().top;
+                               if (topOffset < 0) {
+                                       $(this).css('top', pos.top - topOffset);
+                               }
+                       }
+               },
+               resizable: true,
+               show: null,
+               stack: true,
+               title: '',
+               width: 300,
+               zIndex: 1000
+       },
+
+       _create: function() {
+               this.originalTitle = this.element.attr('title');
+               // #5742 - .attr() might return a DOMElement
+               if ( typeof this.originalTitle !== "string" ) {
+                       this.originalTitle = "";
+               }
+
+               this.options.title = this.options.title || this.originalTitle;
+               var self = this,
+                       options = self.options,
+
+                       title = options.title || '&#160;',
+                       titleId = $.ui.dialog.getTitleId(self.element),
+
+                       uiDialog = (self.uiDialog = $('<div></div>'))
+                               .appendTo(document.body)
+                               .hide()
+                               .addClass(uiDialogClasses + options.dialogClass)
+                               .css({
+                                       zIndex: options.zIndex
+                               })
+                               // setting tabIndex makes the div focusable
+                               // setting outline to 0 prevents a border on focus in Mozilla
+                               .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
+                                       if (options.closeOnEscape && event.keyCode &&
+                                               event.keyCode === $.ui.keyCode.ESCAPE) {
+                                               
+                                               self.close(event);
+                                               event.preventDefault();
+                                       }
+                               })
+                               .attr({
+                                       role: 'dialog',
+                                       'aria-labelledby': titleId
+                               })
+                               .mousedown(function(event) {
+                                       self.moveToTop(false, event);
+                               }),
+
+                       uiDialogContent = self.element
+                               .show()
+                               .removeAttr('title')
+                               .addClass(
+                                       'ui-dialog-content ' +
+                                       'ui-widget-content')
+                               .appendTo(uiDialog),
+
+                       uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
+                               .addClass(
+                                       'ui-dialog-titlebar ' +
+                                       'ui-widget-header ' +
+                                       'ui-corner-top ' +
+                                       'ui-helper-clearfix'
+                               )
+                               .prependTo(uiDialog),
+
+                       uiDialogTitlebarClose = $('<a href="#"></a>')
+                               .addClass(
+                                       'ui-dialog-titlebar-close ' +
+                                       'ui-corner-all'
+                               )
+                               .attr('role', 'button')
+                               .hover(
+                                       function() {
+                                               uiDialogTitlebarClose.addClass('ui-state-hover');
+                                       },
+                                       function() {
+                                               uiDialogTitlebarClose.removeClass('ui-state-hover');
+                                       }
+                               )
+                               .focus(function() {
+                                       uiDialogTitlebarClose.addClass('ui-state-focus');
+                               })
+                               .blur(function() {
+                                       uiDialogTitlebarClose.removeClass('ui-state-focus');
+                               })
+                               .click(function(event) {
+                                       self.close(event);
+                                       return false;
+                               })
+                               .appendTo(uiDialogTitlebar),
+
+                       uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
+                               .addClass(
+                                       'ui-icon ' +
+                                       'ui-icon-closethick'
+                               )
+                               .text(options.closeText)
+                               .appendTo(uiDialogTitlebarClose),
+
+                       uiDialogTitle = $('<span></span>')
+                               .addClass('ui-dialog-title')
+                               .attr('id', titleId)
+                               .html(title)
+                               .prependTo(uiDialogTitlebar);
+
+               //handling of deprecated beforeclose (vs beforeClose) option
+               //Ticket #4669 http://dev.jqueryui.com/ticket/4669
+               //TODO: remove in 1.9pre
+               if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
+                       options.beforeClose = options.beforeclose;
+               }
+
+               uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
+
+               if (options.draggable && $.fn.draggable) {
+                       self._makeDraggable();
+               }
+               if (options.resizable && $.fn.resizable) {
+                       self._makeResizable();
+               }
+
+               self._createButtons(options.buttons);
+               self._isOpen = false;
+
+               if ($.fn.bgiframe) {
+                       uiDialog.bgiframe();
+               }
+       },
+
+       _init: function() {
+               if ( this.options.autoOpen ) {
+                       this.open();
+               }
+       },
+
+       destroy: function() {
+               var self = this;
+               
+               if (self.overlay) {
+                       self.overlay.destroy();
+               }
+               self.uiDialog.hide();
+               self.element
+                       .unbind('.dialog')
+                       .removeData('dialog')
+                       .removeClass('ui-dialog-content ui-widget-content')
+                       .hide().appendTo('body');
+               self.uiDialog.remove();
+
+               if (self.originalTitle) {
+                       self.element.attr('title', self.originalTitle);
+               }
+
+               return self;
+       },
+
+       widget: function() {
+               return this.uiDialog;
+       },
+
+       close: function(event) {
+               var self = this,
+                       maxZ, thisZ;
+               
+               if (false === self._trigger('beforeClose', event)) {
+                       return;
+               }
+
+               if (self.overlay) {
+                       self.overlay.destroy();
+               }
+               self.uiDialog.unbind('keypress.ui-dialog');
+
+               self._isOpen = false;
+
+               if (self.options.hide) {
+                       self.uiDialog.hide(self.options.hide, function() {
+                               self._trigger('close', event);
+                       });
+               } else {
+                       self.uiDialog.hide();
+                       self._trigger('close', event);
+               }
+
+               $.ui.dialog.overlay.resize();
+
+               // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
+               if (self.options.modal) {
+                       maxZ = 0;
+                       $('.ui-dialog').each(function() {
+                               if (this !== self.uiDialog[0]) {
+                                       thisZ = $(this).css('z-index');
+                                       if(!isNaN(thisZ)) {
+                                               maxZ = Math.max(maxZ, thisZ);
+                                       }
+                               }
+                       });
+                       $.ui.dialog.maxZ = maxZ;
+               }
+
+               return self;
+       },
+
+       isOpen: function() {
+               return this._isOpen;
+       },
+
+       // the force parameter allows us to move modal dialogs to their correct
+       // position on open
+       moveToTop: function(force, event) {
+               var self = this,
+                       options = self.options,
+                       saveScroll;
+
+               if ((options.modal && !force) ||
+                       (!options.stack && !options.modal)) {
+                       return self._trigger('focus', event);
+               }
+
+               if (options.zIndex > $.ui.dialog.maxZ) {
+                       $.ui.dialog.maxZ = options.zIndex;
+               }
+               if (self.overlay) {
+                       $.ui.dialog.maxZ += 1;
+                       self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
+               }
+
+               //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
+               //  http://ui.jquery.com/bugs/ticket/3193
+               saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') };
+               $.ui.dialog.maxZ += 1;
+               self.uiDialog.css('z-index', $.ui.dialog.maxZ);
+               self.element.attr(saveScroll);
+               self._trigger('focus', event);
+
+               return self;
+       },
+
+       open: function() {
+               if (this._isOpen) { return; }
+
+               var self = this,
+                       options = self.options,
+                       uiDialog = self.uiDialog;
+
+               self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
+               self._size();
+               self._position(options.position);
+               uiDialog.show(options.show);
+               self.moveToTop(true);
+
+               // prevent tabbing out of modal dialogs
+               if (options.modal) {
+                       uiDialog.bind('keypress.ui-dialog', function(event) {
+                               if (event.keyCode !== $.ui.keyCode.TAB) {
+                                       return;
+                               }
+
+                               var tabbables = $(':tabbable', this),
+                                       first = tabbables.filter(':first'),
+                                       last  = tabbables.filter(':last');
+
+                               if (event.target === last[0] && !event.shiftKey) {
+                                       first.focus(1);
+                                       return false;
+                               } else if (event.target === first[0] && event.shiftKey) {
+                                       last.focus(1);
+                                       return false;
+                               }
+                       });
+               }
+
+               // set focus to the first tabbable element in the content area or the first button
+               // if there are no tabbable elements, set focus on the dialog itself
+               $(self.element.find(':tabbable').get().concat(
+                       uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
+                               uiDialog.get()))).eq(0).focus();
+
+               self._isOpen = true;
+               self._trigger('open');
+
+               return self;
+       },
+
+       _createButtons: function(buttons) {
+               var self = this,
+                       hasButtons = false,
+                       uiDialogButtonPane = $('<div></div>')
+                               .addClass(
+                                       'ui-dialog-buttonpane ' +
+                                       'ui-widget-content ' +
+                                       'ui-helper-clearfix'
+                               ),
+                       uiButtonSet = $( "<div></div>" )
+                               .addClass( "ui-dialog-buttonset" )
+                               .appendTo( uiDialogButtonPane );
+
+               // if we already have a button pane, remove it
+               self.uiDialog.find('.ui-dialog-buttonpane').remove();
+
+               if (typeof buttons === 'object' && buttons !== null) {
+                       $.each(buttons, function() {
+                               return !(hasButtons = true);
+                       });
+               }
+               if (hasButtons) {
+                       $.each(buttons, function(name, props) {
+                               props = $.isFunction( props ) ?
+                                       { click: props, text: name } :
+                                       props;
+                               var button = $('<button type="button"></button>')
+                                       .click(function() {
+                                               props.click.apply(self.element[0], arguments);
+                                       })
+                                       .appendTo(uiButtonSet);
+                               // can't use .attr( props, true ) with jQuery 1.3.2.
+                               $.each( props, function( key, value ) {
+                                       if ( key === "click" ) {
+                                               return;
+                                       }
+                                       if ( key in attrFn ) {
+                                               button[ key ]( value );
+                                       } else {
+                                               button.attr( key, value );
+                                       }
+                               });
+                               if ($.fn.button) {
+                                       button.button();
+                               }
+                       });
+                       uiDialogButtonPane.appendTo(self.uiDialog);
+               }
+       },
+
+       _makeDraggable: function() {
+               var self = this,
+                       options = self.options,
+                       doc = $(document),
+                       heightBeforeDrag;
+
+               function filteredUi(ui) {
+                       return {
+                               position: ui.position,
+                               offset: ui.offset
+                       };
+               }
+
+               self.uiDialog.draggable({
+                       cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
+                       handle: '.ui-dialog-titlebar',
+                       containment: 'document',
+                       start: function(event, ui) {
+                               heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
+                               $(this).height($(this).height()).addClass("ui-dialog-dragging");
+                               self._trigger('dragStart', event, filteredUi(ui));
+                       },
+                       drag: function(event, ui) {
+                               self._trigger('drag', event, filteredUi(ui));
+                       },
+                       stop: function(event, ui) {
+                               options.position = [ui.position.left - doc.scrollLeft(),
+                                       ui.position.top - doc.scrollTop()];
+                               $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
+                               self._trigger('dragStop', event, filteredUi(ui));
+                               $.ui.dialog.overlay.resize();
+                       }
+               });
+       },
+
+       _makeResizable: function(handles) {
+               handles = (handles === undefined ? this.options.resizable : handles);
+               var self = this,
+                       options = self.options,
+                       // .ui-resizable has position: relative defined in the stylesheet
+                       // but dialogs have to use absolute or fixed positioning
+                       position = self.uiDialog.css('position'),
+                       resizeHandles = (typeof handles === 'string' ?
+                               handles :
+                               'n,e,s,w,se,sw,ne,nw'
+                       );
+
+               function filteredUi(ui) {
+                       return {
+                               originalPosition: ui.originalPosition,
+                               originalSize: ui.originalSize,
+                               position: ui.position,
+                               size: ui.size
+                       };
+               }
+
+               self.uiDialog.resizable({
+                       cancel: '.ui-dialog-content',
+                       containment: 'document',
+                       alsoResize: self.element,
+                       maxWidth: options.maxWidth,
+                       maxHeight: options.maxHeight,
+                       minWidth: options.minWidth,
+                       minHeight: self._minHeight(),
+                       handles: resizeHandles,
+                       start: function(event, ui) {
+                               $(this).addClass("ui-dialog-resizing");
+                               self._trigger('resizeStart', event, filteredUi(ui));
+                       },
+                       resize: function(event, ui) {
+                               self._trigger('resize', event, filteredUi(ui));
+                       },
+                       stop: function(event, ui) {
+                               $(this).removeClass("ui-dialog-resizing");
+                               options.height = $(this).height();
+                               options.width = $(this).width();
+                               self._trigger('resizeStop', event, filteredUi(ui));
+                               $.ui.dialog.overlay.resize();
+                       }
+               })
+               .css('position', position)
+               .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
+       },
+
+       _minHeight: function() {
+               var options = this.options;
+
+               if (options.height === 'auto') {
+                       return options.minHeight;
+               } else {
+                       return Math.min(options.minHeight, options.height);
+               }
+       },
+
+       _position: function(position) {
+               var myAt = [],
+                       offset = [0, 0],
+                       isVisible;
+
+               if (position) {
+                       // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
+       //              if (typeof position == 'string' || $.isArray(position)) {
+       //                      myAt = $.isArray(position) ? position : position.split(' ');
+
+                       if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
+                               myAt = position.split ? position.split(' ') : [position[0], position[1]];
+                               if (myAt.length === 1) {
+                                       myAt[1] = myAt[0];
+                               }
+
+                               $.each(['left', 'top'], function(i, offsetPosition) {
+                                       if (+myAt[i] === myAt[i]) {
+                                               offset[i] = myAt[i];
+                                               myAt[i] = offsetPosition;
+                                       }
+                               });
+
+                               position = {
+                                       my: myAt.join(" "),
+                                       at: myAt.join(" "),
+                                       offset: offset.join(" ")
+                               };
+                       } 
+
+                       position = $.extend({}, $.ui.dialog.prototype.options.position, position);
+               } else {
+                       position = $.ui.dialog.prototype.options.position;
+               }
+
+               // need to show the dialog to get the actual offset in the position plugin
+               isVisible = this.uiDialog.is(':visible');
+               if (!isVisible) {
+                       this.uiDialog.show();
+               }
+               this.uiDialog
+                       // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
+                       .css({ top: 0, left: 0 })
+                       .position($.extend({ of: window }, position));
+               if (!isVisible) {
+                       this.uiDialog.hide();
+               }
+       },
+
+       _setOptions: function( options ) {
+               var self = this,
+                       resizableOptions = {},
+                       resize = false;
+
+               $.each( options, function( key, value ) {
+                       self._setOption( key, value );
+                       
+                       if ( key in sizeRelatedOptions ) {
+                               resize = true;
+                       }
+                       if ( key in resizableRelatedOptions ) {
+                               resizableOptions[ key ] = value;
+                       }
+               });
+
+               if ( resize ) {
+                       this._size();
+               }
+               if ( this.uiDialog.is( ":data(resizable)" ) ) {
+                       this.uiDialog.resizable( "option", resizableOptions );
+               }
+       },
+
+       _setOption: function(key, value){
+               var self = this,
+                       uiDialog = self.uiDialog;
+
+               switch (key) {
+                       //handling of deprecated beforeclose (vs beforeClose) option
+                       //Ticket #4669 http://dev.jqueryui.com/ticket/4669
+                       //TODO: remove in 1.9pre
+                       case "beforeclose":
+                               key = "beforeClose";
+                               break;
+                       case "buttons":
+                               self._createButtons(value);
+                               break;
+                       case "closeText":
+                               // ensure that we always pass a string
+                               self.uiDialogTitlebarCloseText.text("" + value);
+                               break;
+                       case "dialogClass":
+                               uiDialog
+                                       .removeClass(self.options.dialogClass)
+                                       .addClass(uiDialogClasses + value);
+                               break;
+                       case "disabled":
+                               if (value) {
+                                       uiDialog.addClass('ui-dialog-disabled');
+                               } else {
+                                       uiDialog.removeClass('ui-dialog-disabled');
+                               }
+                               break;
+                       case "draggable":
+                               var isDraggable = uiDialog.is( ":data(draggable)" );
+                               if ( isDraggable && !value ) {
+                                       uiDialog.draggable( "destroy" );
+                               }
+                               
+                               if ( !isDraggable && value ) {
+                                       self._makeDraggable();
+                               }
+                               break;
+                       case "position":
+                               self._position(value);
+                               break;
+                       case "resizable":
+                               // currently resizable, becoming non-resizable
+                               var isResizable = uiDialog.is( ":data(resizable)" );
+                               if (isResizable && !value) {
+                                       uiDialog.resizable('destroy');
+                               }
+
+                               // currently resizable, changing handles
+                               if (isResizable && typeof value === 'string') {
+                                       uiDialog.resizable('option', 'handles', value);
+                               }
+
+                               // currently non-resizable, becoming resizable
+                               if (!isResizable && value !== false) {
+                                       self._makeResizable(value);
+                               }
+                               break;
+                       case "title":
+                               // convert whatever was passed in o a string, for html() to not throw up
+                               $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
+                               break;
+               }
+
+               $.Widget.prototype._setOption.apply(self, arguments);
+       },
+
+       _size: function() {
+               /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
+                * divs will both have width and height set, so we need to reset them
+                */
+               var options = this.options,
+                       nonContentHeight,
+                       minContentHeight,
+                       isVisible = this.uiDialog.is( ":visible" );
+
+               // reset content sizing
+               this.element.show().css({
+                       width: 'auto',
+                       minHeight: 0,
+                       height: 0
+               });
+
+               if (options.minWidth > options.width) {
+                       options.width = options.minWidth;
+               }
+
+               // reset wrapper sizing
+               // determine the height of all the non-content elements
+               nonContentHeight = this.uiDialog.css({
+                               height: 'auto',
+                               width: options.width
+                       })
+                       .height();
+               minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
+               
+               if ( options.height === "auto" ) {
+                       // only needed for IE6 support
+                       if ( $.support.minHeight ) {
+                               this.element.css({
+                                       minHeight: minContentHeight,
+                                       height: "auto"
+                               });
+                       } else {
+                               this.uiDialog.show();
+                               var autoHeight = this.element.css( "height", "auto" ).height();
+                               if ( !isVisible ) {
+                                       this.uiDialog.hide();
+                               }
+                               this.element.height( Math.max( autoHeight, minContentHeight ) );
+                       }
+               } else {
+                       this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
+               }
+
+               if (this.uiDialog.is(':data(resizable)')) {
+                       this.uiDialog.resizable('option', 'minHeight', this._minHeight());
+               }
+       }
+});
+
+$.extend($.ui.dialog, {
+       version: "1.8.12",
+
+       uuid: 0,
+       maxZ: 0,
+
+       getTitleId: function($el) {
+               var id = $el.attr('id');
+               if (!id) {
+                       this.uuid += 1;
+                       id = this.uuid;
+               }
+               return 'ui-dialog-title-' + id;
+       },
+
+       overlay: function(dialog) {
+               this.$el = $.ui.dialog.overlay.create(dialog);
+       }
+});
+
+$.extend($.ui.dialog.overlay, {
+       instances: [],
+       // reuse old instances due to IE memory leak with alpha transparency (see #5185)
+       oldInstances: [],
+       maxZ: 0,
+       events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
+               function(event) { return event + '.dialog-overlay'; }).join(' '),
+       create: function(dialog) {
+               if (this.instances.length === 0) {
+                       // prevent use of anchors and inputs
+                       // we use a setTimeout in case the overlay is created from an
+                       // event that we're going to be cancelling (see #2804)
+                       setTimeout(function() {
+                               // handle $(el).dialog().dialog('close') (see #4065)
+                               if ($.ui.dialog.overlay.instances.length) {
+                                       $(document).bind($.ui.dialog.overlay.events, function(event) {
+                                               // stop events if the z-index of the target is < the z-index of the overlay
+                                               // we cannot return true when we don't want to cancel the event (#3523)
+                                               if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
+                                                       return false;
+                                               }
+                                       });
+                               }
+                       }, 1);
+
+                       // allow closing by pressing the escape key
+                       $(document).bind('keydown.dialog-overlay', function(event) {
+                               if (dialog.options.closeOnEscape && event.keyCode &&
+                                       event.keyCode === $.ui.keyCode.ESCAPE) {
+                                       
+                                       dialog.close(event);
+                                       event.preventDefault();
+                               }
+                       });
+
+                       // handle window resize
+                       $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
+               }
+
+               var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
+                       .appendTo(document.body)
+                       .css({
+                               width: this.width(),
+                               height: this.height()
+                       });
+
+               if ($.fn.bgiframe) {
+                       $el.bgiframe();
+               }
+
+               this.instances.push($el);
+               return $el;
+       },
+
+       destroy: function($el) {
+               var indexOf = $.inArray($el, this.instances);
+               if (indexOf != -1){
+                       this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
+               }
+
+               if (this.instances.length === 0) {
+                       $([document, window]).unbind('.dialog-overlay');
+               }
+
+               $el.remove();
+               
+               // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
+               var maxZ = 0;
+               $.each(this.instances, function() {
+                       maxZ = Math.max(maxZ, this.css('z-index'));
+               });
+               this.maxZ = maxZ;
+       },
+
+       height: function() {
+               var scrollHeight,
+                       offsetHeight;
+               // handle IE 6
+               if ($.browser.msie && $.browser.version < 7) {
+                       scrollHeight = Math.max(
+                               document.documentElement.scrollHeight,
+                               document.body.scrollHeight
+                       );
+                       offsetHeight = Math.max(
+                               document.documentElement.offsetHeight,
+                               document.body.offsetHeight
+                       );
+
+                       if (scrollHeight < offsetHeight) {
+                               return $(window).height() + 'px';
+                       } else {
+                               return scrollHeight + 'px';
+                       }
+               // handle "good" browsers
+               } else {
+                       return $(document).height() + 'px';
+               }
+       },
+
+       width: function() {
+               var scrollWidth,
+                       offsetWidth;
+               // handle IE 6
+               if ($.browser.msie && $.browser.version < 7) {
+                       scrollWidth = Math.max(
+                               document.documentElement.scrollWidth,
+                               document.body.scrollWidth
+                       );
+                       offsetWidth = Math.max(
+                               document.documentElement.offsetWidth,
+                               document.body.offsetWidth
+                       );
+
+                       if (scrollWidth < offsetWidth) {
+                               return $(window).width() + 'px';
+                       } else {
+                               return scrollWidth + 'px';
+                       }
+               // handle "good" browsers
+               } else {
+                       return $(document).width() + 'px';
+               }
+       },
+
+       resize: function() {
+               /* If the dialog is draggable and the user drags it past the
+                * right edge of the window, the document becomes wider so we
+                * need to stretch the overlay. If the user then drags the
+                * dialog back to the left, the document will become narrower,
+                * so we need to shrink the overlay to the appropriate size.
+                * This is handled by shrinking the overlay before setting it
+                * to the full document size.
+                */
+               var $overlays = $([]);
+               $.each($.ui.dialog.overlay.instances, function() {
+                       $overlays = $overlays.add(this);
+               });
+
+               $overlays.css({
+                       width: 0,
+                       height: 0
+               }).css({
+                       width: $.ui.dialog.overlay.width(),
+                       height: $.ui.dialog.overlay.height()
+               });
+       }
+});
+
+$.extend($.ui.dialog.overlay.prototype, {
+       destroy: function() {
+               $.ui.dialog.overlay.destroy(this.$el);
+       }
+});
+
+}(jQuery));
+/*
+ * jQuery UI Position 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Position
+ */
+(function( $, undefined ) {
+
+$.ui = $.ui || {};
+
+var horizontalPositions = /left|center|right/,
+       verticalPositions = /top|center|bottom/,
+       center = "center",
+       _position = $.fn.position,
+       _offset = $.fn.offset;
+
+$.fn.position = function( options ) {
+       if ( !options || !options.of ) {
+               return _position.apply( this, arguments );
+       }
+
+       // make a copy, we don't want to modify arguments
+       options = $.extend( {}, options );
+
+       var target = $( options.of ),
+               targetElem = target[0],
+               collision = ( options.collision || "flip" ).split( " " ),
+               offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
+               targetWidth,
+               targetHeight,
+               basePosition;
+
+       if ( targetElem.nodeType === 9 ) {
+               targetWidth = target.width();
+               targetHeight = target.height();
+               basePosition = { top: 0, left: 0 };
+       // TODO: use $.isWindow() in 1.9
+       } else if ( targetElem.setTimeout ) {
+               targetWidth = target.width();
+               targetHeight = target.height();
+               basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
+       } else if ( targetElem.preventDefault ) {
+               // force left top to allow flipping
+               options.at = "left top";
+               targetWidth = targetHeight = 0;
+               basePosition = { top: options.of.pageY, left: options.of.pageX };
+       } else {
+               targetWidth = target.outerWidth();
+               targetHeight = target.outerHeight();
+               basePosition = target.offset();
+       }
+
+       // force my and at to have valid horizontal and veritcal positions
+       // if a value is missing or invalid, it will be converted to center 
+       $.each( [ "my", "at" ], function() {
+               var pos = ( options[this] || "" ).split( " " );
+               if ( pos.length === 1) {
+                       pos = horizontalPositions.test( pos[0] ) ?
+                               pos.concat( [center] ) :
+                               verticalPositions.test( pos[0] ) ?
+                                       [ center ].concat( pos ) :
+                                       [ center, center ];
+               }
+               pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
+               pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
+               options[ this ] = pos;
+       });
+
+       // normalize collision option
+       if ( collision.length === 1 ) {
+               collision[ 1 ] = collision[ 0 ];
+       }
+
+       // normalize offset option
+       offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
+       if ( offset.length === 1 ) {
+               offset[ 1 ] = offset[ 0 ];
+       }
+       offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
+
+       if ( options.at[0] === "right" ) {
+               basePosition.left += targetWidth;
+       } else if ( options.at[0] === center ) {
+               basePosition.left += targetWidth / 2;
+       }
+
+       if ( options.at[1] === "bottom" ) {
+               basePosition.top += targetHeight;
+       } else if ( options.at[1] === center ) {
+               basePosition.top += targetHeight / 2;
+       }
+
+       basePosition.left += offset[ 0 ];
+       basePosition.top += offset[ 1 ];
+
+       return this.each(function() {
+               var elem = $( this ),
+                       elemWidth = elem.outerWidth(),
+                       elemHeight = elem.outerHeight(),
+                       marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
+                       marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
+                       collisionWidth = elemWidth + marginLeft +
+                               ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
+                       collisionHeight = elemHeight + marginTop +
+                               ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
+                       position = $.extend( {}, basePosition ),
+                       collisionPosition;
+
+               if ( options.my[0] === "right" ) {
+                       position.left -= elemWidth;
+               } else if ( options.my[0] === center ) {
+                       position.left -= elemWidth / 2;
+               }
+
+               if ( options.my[1] === "bottom" ) {
+                       position.top -= elemHeight;
+               } else if ( options.my[1] === center ) {
+                       position.top -= elemHeight / 2;
+               }
+
+               // prevent fractions (see #5280)
+               position.left = Math.round( position.left );
+               position.top = Math.round( position.top );
+
+               collisionPosition = {
+                       left: position.left - marginLeft,
+                       top: position.top - marginTop
+               };
+
+               $.each( [ "left", "top" ], function( i, dir ) {
+                       if ( $.ui.position[ collision[i] ] ) {
+                               $.ui.position[ collision[i] ][ dir ]( position, {
+                                       targetWidth: targetWidth,
+                                       targetHeight: targetHeight,
+                                       elemWidth: elemWidth,
+                                       elemHeight: elemHeight,
+                                       collisionPosition: collisionPosition,
+                                       collisionWidth: collisionWidth,
+                                       collisionHeight: collisionHeight,
+                                       offset: offset,
+                                       my: options.my,
+                                       at: options.at
+                               });
+                       }
+               });
+
+               if ( $.fn.bgiframe ) {
+                       elem.bgiframe();
+               }
+               elem.offset( $.extend( position, { using: options.using } ) );
+       });
+};
+
+$.ui.position = {
+       fit: {
+               left: function( position, data ) {
+                       var win = $( window ),
+                               over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
+                       position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
+               },
+               top: function( position, data ) {
+                       var win = $( window ),
+                               over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
+                       position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
+               }
+       },
+
+       flip: {
+               left: function( position, data ) {
+                       if ( data.at[0] === center ) {
+                               return;
+                       }
+                       var win = $( window ),
+                               over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
+                               myOffset = data.my[ 0 ] === "left" ?
+                                       -data.elemWidth :
+                                       data.my[ 0 ] === "right" ?
+                                               data.elemWidth :
+                                               0,
+                               atOffset = data.at[ 0 ] === "left" ?
+                                       data.targetWidth :
+                                       -data.targetWidth,
+                               offset = -2 * data.offset[ 0 ];
+                       position.left += data.collisionPosition.left < 0 ?
+                               myOffset + atOffset + offset :
+                               over > 0 ?
+                                       myOffset + atOffset + offset :
+                                       0;
+               },
+               top: function( position, data ) {
+                       if ( data.at[1] === center ) {
+                               return;
+                       }
+                       var win = $( window ),
+                               over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
+                               myOffset = data.my[ 1 ] === "top" ?
+                                       -data.elemHeight :
+                                       data.my[ 1 ] === "bottom" ?
+                                               data.elemHeight :
+                                               0,
+                               atOffset = data.at[ 1 ] === "top" ?
+                                       data.targetHeight :
+                                       -data.targetHeight,
+                               offset = -2 * data.offset[ 1 ];
+                       position.top += data.collisionPosition.top < 0 ?
+                               myOffset + atOffset + offset :
+                               over > 0 ?
+                                       myOffset + atOffset + offset :
+                                       0;
+               }
+       }
+};
+
+// offset setter from jQuery 1.4
+if ( !$.offset.setOffset ) {
+       $.offset.setOffset = function( elem, options ) {
+               // set position first, in-case top/left are set even on static elem
+               if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
+                       elem.style.position = "relative";
+               }
+               var curElem   = $( elem ),
+                       curOffset = curElem.offset(),
+                       curTop    = parseInt( $.curCSS( elem, "top",  true ), 10 ) || 0,
+                       curLeft   = parseInt( $.curCSS( elem, "left", true ), 10)  || 0,
+                       props     = {
+                               top:  (options.top  - curOffset.top)  + curTop,
+                               left: (options.left - curOffset.left) + curLeft
+                       };
+               
+               if ( 'using' in options ) {
+                       options.using.call( elem, props );
+               } else {
+                       curElem.css( props );
+               }
+       };
+
+       $.fn.offset = function( options ) {
+               var elem = this[ 0 ];
+               if ( !elem || !elem.ownerDocument ) { return null; }
+               if ( options ) { 
+                       return this.each(function() {
+                               $.offset.setOffset( this, options );
+                       });
+               }
+               return _offset.call( this );
+       };
+}
+
+}( jQuery ));
+/*
+ * jQuery UI Progressbar 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar
+ *
+ * Depends:
+ *   jquery.ui.core.js
+ *   jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget( "ui.progressbar", {
+       options: {
+               value: 0,
+               max: 100
+       },
+
+       min: 0,
+
+       _create: function() {
+               this.element
+                       .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
+                       .attr({
+                               role: "progressbar",
+                               "aria-valuemin": this.min,
+                               "aria-valuemax": this.options.max,
+                               "aria-valuenow": this._value()
+                       });
+
+               this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
+                       .appendTo( this.element );
+
+               this.oldValue = this._value();
+               this._refreshValue();
+       },
+
+       destroy: function() {
+               this.element
+                       .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-valuemin" )
+                       .removeAttr( "aria-valuemax" )
+                       .removeAttr( "aria-valuenow" );
+
+               this.valueDiv.remove();
+
+               $.Widget.prototype.destroy.apply( this, arguments );
+       },
+
+       value: function( newValue ) {
+               if ( newValue === undefined ) {
+                       return this._value();
+               }
+
+               this._setOption( "value", newValue );
+               return this;
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "value" ) {
+                       this.options.value = value;
+                       this._refreshValue();
+                       if ( this._value() === this.options.max ) {
+                               this._trigger( "complete" );
+                       }
+               }
+
+               $.Widget.prototype._setOption.apply( this, arguments );
+       },
+
+       _value: function() {
+               var val = this.options.value;
+               // normalize invalid value
+               if ( typeof val !== "number" ) {
+                       val = 0;
+               }
+               return Math.min( this.options.max, Math.max( this.min, val ) );
+       },
+
+       _percentage: function() {
+               return 100 * this._value() / this.options.max;
+       },
+
+       _refreshValue: function() {
+               var value = this.value();
+               var percentage = this._percentage();
+
+               if ( this.oldValue !== value ) {
+                       this.oldValue = value;
+                       this._trigger( "change" );
+               }
+
+               this.valueDiv
+                       .toggle( value > this.min )
+                       .toggleClass( "ui-corner-right", value === this.options.max )
+                       .width( percentage.toFixed(0) + "%" );
+               this.element.attr( "aria-valuenow", value );
+       }
+});
+
+$.extend( $.ui.progressbar, {
+       version: "1.8.12"
+});
+
+})( jQuery );
+/*
+ * jQuery UI Slider 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.mouse.js
+ *     jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+// number of pages in a slider
+// (how many times can you page up/down to go through the whole range)
+var numPages = 5;
+
+$.widget( "ui.slider", $.ui.mouse, {
+
+       widgetEventPrefix: "slide",
+
+       options: {
+               animate: false,
+               distance: 0,
+               max: 100,
+               min: 0,
+               orientation: "horizontal",
+               range: false,
+               step: 1,
+               value: 0,
+               values: null
+       },
+
+       _create: function() {
+               var self = this,
+                       o = this.options;
+
+               this._keySliding = false;
+               this._mouseSliding = false;
+               this._animateOff = true;
+               this._handleIndex = null;
+               this._detectOrientation();
+               this._mouseInit();
+
+               this.element
+                       .addClass( "ui-slider" +
+                               " ui-slider-" + this.orientation +
+                               " ui-widget" +
+                               " ui-widget-content" +
+                               " ui-corner-all" );
+               
+               if ( o.disabled ) {
+                       this.element.addClass( "ui-slider-disabled ui-disabled" );
+               }
+
+               this.range = $([]);
+
+               if ( o.range ) {
+                       if ( o.range === true ) {
+                               this.range = $( "<div></div>" );
+                               if ( !o.values ) {
+                                       o.values = [ this._valueMin(), this._valueMin() ];
+                               }
+                               if ( o.values.length && o.values.length !== 2 ) {
+                                       o.values = [ o.values[0], o.values[0] ];
+                               }
+                       } else {
+                               this.range = $( "<div></div>" );
+                       }
+
+                       this.range
+                               .appendTo( this.element )
+                               .addClass( "ui-slider-range" );
+
+                       if ( o.range === "min" || o.range === "max" ) {
+                               this.range.addClass( "ui-slider-range-" + o.range );
+                       }
+
+                       // note: this isn't the most fittingly semantic framework class for this element,
+                       // but worked best visually with a variety of themes
+                       this.range.addClass( "ui-widget-header" );
+               }
+
+               if ( $( ".ui-slider-handle", this.element ).length === 0 ) {
+                       $( "<a href='#'></a>" )
+                               .appendTo( this.element )
+                               .addClass( "ui-slider-handle" );
+               }
+
+               if ( o.values && o.values.length ) {
+                       while ( $(".ui-slider-handle", this.element).length < o.values.length ) {
+                               $( "<a href='#'></a>" )
+                                       .appendTo( this.element )
+                                       .addClass( "ui-slider-handle" );
+                       }
+               }
+
+               this.handles = $( ".ui-slider-handle", this.element )
+                       .addClass( "ui-state-default" +
+                               " ui-corner-all" );
+
+               this.handle = this.handles.eq( 0 );
+
+               this.handles.add( this.range ).filter( "a" )
+                       .click(function( event ) {
+                               event.preventDefault();
+                       })
+                       .hover(function() {
+                               if ( !o.disabled ) {
+                                       $( this ).addClass( "ui-state-hover" );
+                               }
+                       }, function() {
+                               $( this ).removeClass( "ui-state-hover" );
+                       })
+                       .focus(function() {
+                               if ( !o.disabled ) {
+                                       $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
+                                       $( this ).addClass( "ui-state-focus" );
+                               } else {
+                                       $( this ).blur();
+                               }
+                       })
+                       .blur(function() {
+                               $( this ).removeClass( "ui-state-focus" );
+                       });
+
+               this.handles.each(function( i ) {
+                       $( this ).data( "index.ui-slider-handle", i );
+               });
+
+               this.handles
+                       .keydown(function( event ) {
+                               var ret = true,
+                                       index = $( this ).data( "index.ui-slider-handle" ),
+                                       allowed,
+                                       curVal,
+                                       newVal,
+                                       step;
+       
+                               if ( self.options.disabled ) {
+                                       return;
+                               }
+       
+                               switch ( event.keyCode ) {
+                                       case $.ui.keyCode.HOME:
+                                       case $.ui.keyCode.END:
+                                       case $.ui.keyCode.PAGE_UP:
+                                       case $.ui.keyCode.PAGE_DOWN:
+                                       case $.ui.keyCode.UP:
+                                       case $.ui.keyCode.RIGHT:
+                                       case $.ui.keyCode.DOWN:
+                                       case $.ui.keyCode.LEFT:
+                                               ret = false;
+                                               if ( !self._keySliding ) {
+                                                       self._keySliding = true;
+                                                       $( this ).addClass( "ui-state-active" );
+                                                       allowed = self._start( event, index );
+                                                       if ( allowed === false ) {
+                                                               return;
+                                                       }
+                                               }
+                                               break;
+                               }
+       
+                               step = self.options.step;
+                               if ( self.options.values && self.options.values.length ) {
+                                       curVal = newVal = self.values( index );
+                               } else {
+                                       curVal = newVal = self.value();
+                               }
+       
+                               switch ( event.keyCode ) {
+                                       case $.ui.keyCode.HOME:
+                                               newVal = self._valueMin();
+                                               break;
+                                       case $.ui.keyCode.END:
+                                               newVal = self._valueMax();
+                                               break;
+                                       case $.ui.keyCode.PAGE_UP:
+                                               newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
+                                               break;
+                                       case $.ui.keyCode.PAGE_DOWN:
+                                               newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
+                                               break;
+                                       case $.ui.keyCode.UP:
+                                       case $.ui.keyCode.RIGHT:
+                                               if ( curVal === self._valueMax() ) {
+                                                       return;
+                                               }
+                                               newVal = self._trimAlignValue( curVal + step );
+                                               break;
+                                       case $.ui.keyCode.DOWN:
+                                       case $.ui.keyCode.LEFT:
+                                               if ( curVal === self._valueMin() ) {
+                                                       return;
+                                               }
+                                               newVal = self._trimAlignValue( curVal - step );
+                                               break;
+                               }
+       
+                               self._slide( event, index, newVal );
+       
+                               return ret;
+       
+                       })
+                       .keyup(function( event ) {
+                               var index = $( this ).data( "index.ui-slider-handle" );
+       
+                               if ( self._keySliding ) {
+                                       self._keySliding = false;
+                                       self._stop( event, index );
+                                       self._change( event, index );
+                                       $( this ).removeClass( "ui-state-active" );
+                               }
+       
+                       });
+
+               this._refreshValue();
+
+               this._animateOff = false;
+       },
+
+       destroy: function() {
+               this.handles.remove();
+               this.range.remove();
+
+               this.element
+                       .removeClass( "ui-slider" +
+                               " ui-slider-horizontal" +
+                               " ui-slider-vertical" +
+                               " ui-slider-disabled" +
+                               " ui-widget" +
+                               " ui-widget-content" +
+                               " ui-corner-all" )
+                       .removeData( "slider" )
+                       .unbind( ".slider" );
+
+               this._mouseDestroy();
+
+               return this;
+       },
+
+       _mouseCapture: function( event ) {
+               var o = this.options,
+                       position,
+                       normValue,
+                       distance,
+                       closestHandle,
+                       self,
+                       index,
+                       allowed,
+                       offset,
+                       mouseOverHandle;
+
+               if ( o.disabled ) {
+                       return false;
+               }
+
+               this.elementSize = {
+                       width: this.element.outerWidth(),
+                       height: this.element.outerHeight()
+               };
+               this.elementOffset = this.element.offset();
+
+               position = { x: event.pageX, y: event.pageY };
+               normValue = this._normValueFromMouse( position );
+               distance = this._valueMax() - this._valueMin() + 1;
+               self = this;
+               this.handles.each(function( i ) {
+                       var thisDistance = Math.abs( normValue - self.values(i) );
+                       if ( distance > thisDistance ) {
+                               distance = thisDistance;
+                               closestHandle = $( this );
+                               index = i;
+                       }
+               });
+
+               // workaround for bug #3736 (if both handles of a range are at 0,
+               // the first is always used as the one with least distance,
+               // and moving it is obviously prevented by preventing negative ranges)
+               if( o.range === true && this.values(1) === o.min ) {
+                       index += 1;
+                       closestHandle = $( this.handles[index] );
+               }
+
+               allowed = this._start( event, index );
+               if ( allowed === false ) {
+                       return false;
+               }
+               this._mouseSliding = true;
+
+               self._handleIndex = index;
+
+               closestHandle
+                       .addClass( "ui-state-active" )
+                       .focus();
+               
+               offset = closestHandle.offset();
+               mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
+               this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
+                       left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
+                       top: event.pageY - offset.top -
+                               ( closestHandle.height() / 2 ) -
+                               ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
+                               ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
+                               ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
+               };
+
+               if ( !this.handles.hasClass( "ui-state-hover" ) ) {
+                       this._slide( event, index, normValue );
+               }
+               this._animateOff = true;
+               return true;
+       },
+
+       _mouseStart: function( event ) {
+               return true;
+       },
+
+       _mouseDrag: function( event ) {
+               var position = { x: event.pageX, y: event.pageY },
+                       normValue = this._normValueFromMouse( position );
+               
+               this._slide( event, this._handleIndex, normValue );
+
+               return false;
+       },
+
+       _mouseStop: function( event ) {
+               this.handles.removeClass( "ui-state-active" );
+               this._mouseSliding = false;
+
+               this._stop( event, this._handleIndex );
+               this._change( event, this._handleIndex );
+
+               this._handleIndex = null;
+               this._clickOffset = null;
+               this._animateOff = false;
+
+               return false;
+       },
+       
+       _detectOrientation: function() {
+               this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
+       },
+
+       _normValueFromMouse: function( position ) {
+               var pixelTotal,
+                       pixelMouse,
+                       percentMouse,
+                       valueTotal,
+                       valueMouse;
+
+               if ( this.orientation === "horizontal" ) {
+                       pixelTotal = this.elementSize.width;
+                       pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
+               } else {
+                       pixelTotal = this.elementSize.height;
+                       pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
+               }
+
+               percentMouse = ( pixelMouse / pixelTotal );
+               if ( percentMouse > 1 ) {
+                       percentMouse = 1;
+               }
+               if ( percentMouse < 0 ) {
+                       percentMouse = 0;
+               }
+               if ( this.orientation === "vertical" ) {
+                       percentMouse = 1 - percentMouse;
+               }
+
+               valueTotal = this._valueMax() - this._valueMin();
+               valueMouse = this._valueMin() + percentMouse * valueTotal;
+
+               return this._trimAlignValue( valueMouse );
+       },
+
+       _start: function( event, index ) {
+               var uiHash = {
+                       handle: this.handles[ index ],
+                       value: this.value()
+               };
+               if ( this.options.values && this.options.values.length ) {
+                       uiHash.value = this.values( index );
+                       uiHash.values = this.values();
+               }
+               return this._trigger( "start", event, uiHash );
+       },
+
+       _slide: function( event, index, newVal ) {
+               var otherVal,
+                       newValues,
+                       allowed;
+
+               if ( this.options.values && this.options.values.length ) {
+                       otherVal = this.values( index ? 0 : 1 );
+
+                       if ( ( this.options.values.length === 2 && this.options.range === true ) && 
+                                       ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
+                               ) {
+                               newVal = otherVal;
+                       }
+
+                       if ( newVal !== this.values( index ) ) {
+                               newValues = this.values();
+                               newValues[ index ] = newVal;
+                               // A slide can be canceled by returning false from the slide callback
+                               allowed = this._trigger( "slide", event, {
+                                       handle: this.handles[ index ],
+                                       value: newVal,
+                                       values: newValues
+                               } );
+                               otherVal = this.values( index ? 0 : 1 );
+                               if ( allowed !== false ) {
+                                       this.values( index, newVal, true );
+                               }
+                       }
+               } else {
+                       if ( newVal !== this.value() ) {
+                               // A slide can be canceled by returning false from the slide callback
+                               allowed = this._trigger( "slide", event, {
+                                       handle: this.handles[ index ],
+                                       value: newVal
+                               } );
+                               if ( allowed !== false ) {
+                                       this.value( newVal );
+                               }
+                       }
+               }
+       },
+
+       _stop: function( event, index ) {
+               var uiHash = {
+                       handle: this.handles[ index ],
+                       value: this.value()
+               };
+               if ( this.options.values && this.options.values.length ) {
+                       uiHash.value = this.values( index );
+                       uiHash.values = this.values();
+               }
+
+               this._trigger( "stop", event, uiHash );
+       },
+
+       _change: function( event, index ) {
+               if ( !this._keySliding && !this._mouseSliding ) {
+                       var uiHash = {
+                               handle: this.handles[ index ],
+                               value: this.value()
+                       };
+                       if ( this.options.values && this.options.values.length ) {
+                               uiHash.value = this.values( index );
+                               uiHash.values = this.values();
+                       }
+
+                       this._trigger( "change", event, uiHash );
+               }
+       },
+
+       value: function( newValue ) {
+               if ( arguments.length ) {
+                       this.options.value = this._trimAlignValue( newValue );
+                       this._refreshValue();
+                       this._change( null, 0 );
+                       return;
+               }
+
+               return this._value();
+       },
+
+       values: function( index, newValue ) {
+               var vals,
+                       newValues,
+                       i;
+
+               if ( arguments.length > 1 ) {
+                       this.options.values[ index ] = this._trimAlignValue( newValue );
+                       this._refreshValue();
+                       this._change( null, index );
+                       return;
+               }
+
+               if ( arguments.length ) {
+                       if ( $.isArray( arguments[ 0 ] ) ) {
+                               vals = this.options.values;
+                               newValues = arguments[ 0 ];
+                               for ( i = 0; i < vals.length; i += 1 ) {
+                                       vals[ i ] = this._trimAlignValue( newValues[ i ] );
+                                       this._change( null, i );
+                               }
+                               this._refreshValue();
+                       } else {
+                               if ( this.options.values && this.options.values.length ) {
+                                       return this._values( index );
+                               } else {
+                                       return this.value();
+                               }
+                       }
+               } else {
+                       return this._values();
+               }
+       },
+
+       _setOption: function( key, value ) {
+               var i,
+                       valsLength = 0;
+
+               if ( $.isArray( this.options.values ) ) {
+                       valsLength = this.options.values.length;
+               }
+
+               $.Widget.prototype._setOption.apply( this, arguments );
+
+               switch ( key ) {
+                       case "disabled":
+                               if ( value ) {
+                                       this.handles.filter( ".ui-state-focus" ).blur();
+                                       this.handles.removeClass( "ui-state-hover" );
+                                       this.handles.attr( "disabled", "disabled" );
+                                       this.element.addClass( "ui-disabled" );
+                               } else {
+                                       this.handles.removeAttr( "disabled" );
+                                       this.element.removeClass( "ui-disabled" );
+                               }
+                               break;
+                       case "orientation":
+                               this._detectOrientation();
+                               this.element
+                                       .removeClass( "ui-slider-horizontal ui-slider-vertical" )
+                                       .addClass( "ui-slider-" + this.orientation );
+                               this._refreshValue();
+                               break;
+                       case "value":
+                               this._animateOff = true;
+                               this._refreshValue();
+                               this._change( null, 0 );
+                               this._animateOff = false;
+                               break;
+                       case "values":
+                               this._animateOff = true;
+                               this._refreshValue();
+                               for ( i = 0; i < valsLength; i += 1 ) {
+                                       this._change( null, i );
+                               }
+                               this._animateOff = false;
+                               break;
+               }
+       },
+
+       //internal value getter
+       // _value() returns value trimmed by min and max, aligned by step
+       _value: function() {
+               var val = this.options.value;
+               val = this._trimAlignValue( val );
+
+               return val;
+       },
+
+       //internal values getter
+       // _values() returns array of values trimmed by min and max, aligned by step
+       // _values( index ) returns single value trimmed by min and max, aligned by step
+       _values: function( index ) {
+               var val,
+                       vals,
+                       i;
+
+               if ( arguments.length ) {
+                       val = this.options.values[ index ];
+                       val = this._trimAlignValue( val );
+
+                       return val;
+               } else {
+                       // .slice() creates a copy of the array
+                       // this copy gets trimmed by min and max and then returned
+                       vals = this.options.values.slice();
+                       for ( i = 0; i < vals.length; i+= 1) {
+                               vals[ i ] = this._trimAlignValue( vals[ i ] );
+                       }
+
+                       return vals;
+               }
+       },
+       
+       // returns the step-aligned value that val is closest to, between (inclusive) min and max
+       _trimAlignValue: function( val ) {
+               if ( val <= this._valueMin() ) {
+                       return this._valueMin();
+               }
+               if ( val >= this._valueMax() ) {
+                       return this._valueMax();
+               }
+               var step = ( this.options.step > 0 ) ? this.options.step : 1,
+                       valModStep = (val - this._valueMin()) % step;
+                       alignValue = val - valModStep;
+
+               if ( Math.abs(valModStep) * 2 >= step ) {
+                       alignValue += ( valModStep > 0 ) ? step : ( -step );
+               }
+
+               // Since JavaScript has problems with large floats, round
+               // the final value to 5 digits after the decimal point (see #4124)
+               return parseFloat( alignValue.toFixed(5) );
+       },
+
+       _valueMin: function() {
+               return this.options.min;
+       },
+
+       _valueMax: function() {
+               return this.options.max;
+       },
+       
+       _refreshValue: function() {
+               var oRange = this.options.range,
+                       o = this.options,
+                       self = this,
+                       animate = ( !this._animateOff ) ? o.animate : false,
+                       valPercent,
+                       _set = {},
+                       lastValPercent,
+                       value,
+                       valueMin,
+                       valueMax;
+
+               if ( this.options.values && this.options.values.length ) {
+                       this.handles.each(function( i, j ) {
+                               valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
+                               _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+                               $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+                               if ( self.options.range === true ) {
+                                       if ( self.orientation === "horizontal" ) {
+                                               if ( i === 0 ) {
+                                                       self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
+                                               }
+                                               if ( i === 1 ) {
+                                                       self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
+                                               }
+                                       } else {
+                                               if ( i === 0 ) {
+                                                       self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
+                                               }
+                                               if ( i === 1 ) {
+                                                       self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
+                                               }
+                                       }
+                               }
+                               lastValPercent = valPercent;
+                       });
+               } else {
+                       value = this.value();
+                       valueMin = this._valueMin();
+                       valueMax = this._valueMax();
+                       valPercent = ( valueMax !== valueMin ) ?
+                                       ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
+                                       0;
+                       _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+                       this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+
+                       if ( oRange === "min" && this.orientation === "horizontal" ) {
+                               this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
+                       }
+                       if ( oRange === "max" && this.orientation === "horizontal" ) {
+                               this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
+                       }
+                       if ( oRange === "min" && this.orientation === "vertical" ) {
+                               this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
+                       }
+                       if ( oRange === "max" && this.orientation === "vertical" ) {
+                               this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
+                       }
+               }
+       }
+
+});
+
+$.extend( $.ui.slider, {
+       version: "1.8.12"
+});
+
+}(jQuery));
+/*
+ * jQuery UI Tabs 1.8.12
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+var tabId = 0,
+       listId = 0;
+
+function getNextTabId() {
+       return ++tabId;
+}
+
+function getNextListId() {
+       return ++listId;
+}
+
+$.widget( "ui.tabs", {
+       options: {
+               add: null,
+               ajaxOptions: null,
+               cache: false,
+               cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
+               collapsible: false,
+               disable: null,
+               disabled: [],
+               enable: null,
+               event: "click",
+               fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
+               idPrefix: "ui-tabs-",
+               load: null,
+               panelTemplate: "<div></div>",
+               remove: null,
+               select: null,
+               show: null,
+               spinner: "<em>Loading&#8230;</em>",
+               tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
+       },
+
+       _create: function() {
+               this._tabify( true );
+       },
+
+       _setOption: function( key, value ) {
+               if ( key == "selected" ) {
+                       if (this.options.collapsible && value == this.options.selected ) {
+                               return;
+                       }
+                       this.select( value );
+               } else {
+                       this.options[ key ] = value;
+                       this._tabify();
+               }
+       },
+
+       _tabId: function( a ) {
+               return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
+                       this.options.idPrefix + getNextTabId();
+       },
+
+       _sanitizeSelector: function( hash ) {
+               // we need this because an id may contain a ":"
+               return hash.replace( /:/g, "\\:" );
+       },
+
+       _cookie: function() {
+               var cookie = this.cookie ||
+                       ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
+               return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
+       },
+
+       _ui: function( tab, panel ) {
+               return {
+                       tab: tab,
+                       panel: panel,
+                       index: this.anchors.index( tab )
+               };
+       },
+
+       _cleanup: function() {
+               // restore all former loading tabs labels
+               this.lis.filter( ".ui-state-processing" )
+                       .removeClass( "ui-state-processing" )
+                       .find( "span:data(label.tabs)" )
+                               .each(function() {
+                                       var el = $( this );
+                                       el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
+                               });
+       },
+
+       _tabify: function( init ) {
+               var self = this,
+                       o = this.options,
+                       fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
+
+               this.list = this.element.find( "ol,ul" ).eq( 0 );
+               this.lis = $( " > li:has(a[href])", this.list );
+               this.anchors = this.lis.map(function() {
+                       return $( "a", this )[ 0 ];
+               });
+               this.panels = $( [] );
+
+               this.anchors.each(function( i, a ) {
+                       var href = $( a ).attr( "href" );
+                       // For dynamically created HTML that contains a hash as href IE < 8 expands
+                       // such href to the full page url with hash and then misinterprets tab as ajax.
+                       // Same consideration applies for an added tab with a fragment identifier
+                       // since a[href=#fragment-identifier] does unexpectedly not match.
+                       // Thus normalize href attribute...
+                       var hrefBase = href.split( "#" )[ 0 ],
+                               baseEl;
+                       if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
+                                       ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
+                               href = a.hash;
+                               a.href = href;
+                       }
+
+                       // inline tab
+                       if ( fragmentId.test( href ) ) {
+                               self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
+                       // remote tab
+                       // prevent loading the page itself if href is just "#"
+                       } else if ( href && href !== "#" ) {
+                               // required for restore on destroy
+                               $.data( a, "href.tabs", href );
+
+                               // TODO until #3808 is fixed strip fragment identifier from url
+                               // (IE fails to load from such url)
+                               $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
+
+                               var id = self._tabId( a );
+                               a.href = "#" + id;
+                               var $panel = self.element.find( "#" + id );
+                               if ( !$panel.length ) {
+                                       $panel = $( o.panelTemplate )
+                                               .attr( "id", id )
+                                               .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
+                                               .insertAfter( self.panels[ i - 1 ] || self.list );
+                                       $panel.data( "destroy.tabs", true );
+                               }
+                               self.panels = self.panels.add( $panel );
+                       // invalid tab href
+                       } else {
+                               o.disabled.push( i );
+                       }
+               });
+
+               // initialization from scratch
+               if ( init ) {
+                       // attach necessary classes for styling
+                       this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
+                       this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
+                       this.lis.addClass( "ui-state-default ui-corner-top" );
+                       this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
+
+                       // Selected tab
+                       // use "selected" option or try to retrieve:
+                       // 1. from fragment identifier in url
+                       // 2. from cookie
+                       // 3. from selected class attribute on <li>
+                       if ( o.selected === undefined ) {
+                               if ( location.hash ) {
+                                       this.anchors.each(function( i, a ) {
+                                               if ( a.hash == location.hash ) {
+                                                       o.selected = i;
+                                                       return false;
+                                               }
+                                       });
+                               }
+                               if ( typeof o.selected !== "number" && o.cookie ) {
+                                       o.selected = parseInt( self._cookie(), 10 );
+                               }
+                               if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
+                                       o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
+                               }
+                               o.selected = o.selected || ( this.lis.length ? 0 : -1 );
+                       } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
+                               o.selected = -1;
+                       }
+
+                       // sanity check - default to first tab...
+                       o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
+                               ? o.selected
+                               : 0;
+
+                       // Take disabling tabs via class attribute from HTML
+                       // into account and update option properly.
+                       // A selected tab cannot become disabled.
+                       o.disabled = $.unique( o.disabled.concat(
+                               $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
+                                       return self.lis.index( n );
+                               })
+                       ) ).sort();
+
+                       if ( $.inArray( o.selected, o.disabled ) != -1 ) {
+                               o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
+                       }
+
+                       // highlight selected tab
+                       this.panels.addClass( "ui-tabs-hide" );
+                       this.lis.removeClass( "ui-tabs-selected ui-state-active" );
+                       // check for length avoids error when initializing empty list
+                       if ( o.selected >= 0 && this.anchors.length ) {
+                               self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
+                               this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
+
+                               // seems to be expected behavior that the show callback is fired
+                               self.element.queue( "tabs", function() {
+                                       self._trigger( "show", null,
+                                               self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
+                               });
+
+                               this.load( o.selected );
+                       }
+
+                       // clean up to avoid memory leaks in certain versions of IE 6
+                       // TODO: namespace this event
+                       $( window ).bind( "unload", function() {
+                               self.lis.add( self.anchors ).unbind( ".tabs" );
+                               self.lis = self.anchors = self.panels = null;
+                       });
+               // update selected after add/remove
+               } else {
+                       o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
+               }
+
+               // update collapsible
+               // TODO: use .toggleClass()
+               this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
+
+               // set or update cookie after init and add/remove respectively
+               if ( o.cookie ) {
+                       this._cookie( o.selected, o.cookie );
+               }
+
+               // disable tabs
+               for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
+                       $( li )[ $.inArray( i, o.disabled ) != -1 &&
+                               // TODO: use .toggleClass()
+                               !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
+               }
+
+               // reset cache if switching from cached to not cached
+               if ( o.cache === false ) {
+                       this.anchors.removeData( "cache.tabs" );
+               }
+
+               // remove all handlers before, tabify may run on existing tabs after add or option change
+               this.lis.add( this.anchors ).unbind( ".tabs" );
+
+               if ( o.event !== "mouseover" ) {
+                       var addState = function( state, el ) {
+                               if ( el.is( ":not(.ui-state-disabled)" ) ) {
+                                       el.addClass( "ui-state-" + state );
+                               }
+                       };
+                       var removeState = function( state, el ) {
+                               el.removeClass( "ui-state-" + state );
+                       };
+                       this.lis.bind( "mouseover.tabs" , function() {
+                               addState( "hover", $( this ) );
+                       });
+                       this.lis.bind( "mouseout.tabs", function() {
+                               removeState( "hover", $( this ) );
+                       });
+                       this.anchors.bind( "focus.tabs", function() {
+                               addState( "focus", $( this ).closest( "li" ) );
+                       });
+                       this.anchors.bind( "blur.tabs", function() {
+                               removeState( "focus", $( this ).closest( "li" ) );
+                       });
+               }
+
+               // set up animations
+               var hideFx, showFx;
+               if ( o.fx ) {
+                       if ( $.isArray( o.fx ) ) {
+                               hideFx = o.fx[ 0 ];
+                               showFx = o.fx[ 1 ];
+                       } else {
+                               hideFx = showFx = o.fx;
+                       }
+               }
+
+               // Reset certain styles left over from animation
+               // and prevent IE's ClearType bug...
+               function resetStyle( $el, fx ) {
+                       $el.css( "display", "" );
+                       if ( !$.support.opacity && fx.opacity ) {
+                               $el[ 0 ].style.removeAttribute( "filter" );
+                       }
+               }
+
+               // Show a tab...
+               var showTab = showFx
+                       ? function( clicked, $show ) {
+                               $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
+                               $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
+                                       .animate( showFx, showFx.duration || "normal", function() {
+                                               resetStyle( $show, showFx );
+                                               self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
+                                       });
+                       }
+                       : function( clicked, $show ) {
+                               $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
+                               $show.removeClass( "ui-tabs-hide" );
+                               self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
+                       };
+
+               // Hide a tab, $show is optional...
+               var hideTab = hideFx
+                       ? function( clicked, $hide ) {
+                               $hide.animate( hideFx, hideFx.duration || "normal", function() {
+                                       self.lis.removeClass( "ui-tabs-selected ui-state-active" );
+                                       $hide.addClass( "ui-tabs-hide" );
+                                       resetStyle( $hide, hideFx );
+                                       self.element.dequeue( "tabs" );
+                               });
+                       }
+                       : function( clicked, $hide, $show ) {
+                               self.lis.removeClass( "ui-tabs-selected ui-state-active" );
+                               $hide.addClass( "ui-tabs-hide" );
+                               self.element.dequeue( "tabs" );
+                       };
+
+               // attach tab event handler, unbind to avoid duplicates from former tabifying...
+               this.anchors.bind( o.event + ".tabs", function() {
+                       var el = this,
+                               $li = $(el).closest( "li" ),
+                               $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
+                               $show = self.element.find( self._sanitizeSelector( el.hash ) );
+
+                       // If tab is already selected and not collapsible or tab disabled or
+                       // or is already loading or click callback returns false stop here.
+                       // Check if click handler returns false last so that it is not executed
+                       // for a disabled or loading tab!
+                       if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
+                               $li.hasClass( "ui-state-disabled" ) ||
+                               $li.hasClass( "ui-state-processing" ) ||
+                               self.panels.filter( ":animated" ).length ||
+                               self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
+                               this.blur();
+                               return false;
+                       }
+
+                       o.selected = self.anchors.index( this );
+
+                       self.abort();
+
+                       // if tab may be closed
+                       if ( o.collapsible ) {
+                               if ( $li.hasClass( "ui-tabs-selected" ) ) {
+                                       o.selected = -1;
+
+                                       if ( o.cookie ) {
+                                               self._cookie( o.selected, o.cookie );
+                                       }
+
+                                       self.element.queue( "tabs", function() {
+                                               hideTab( el, $hide );
+                                       }).dequeue( "tabs" );
+
+                                       this.blur();
+                                       return false;
+                               } else if ( !$hide.length ) {
+                                       if ( o.cookie ) {
+                                               self._cookie( o.selected, o.cookie );
+                                       }
+
+                                       self.element.queue( "tabs", function() {
+                                               showTab( el, $show );
+                                       });
+
+                                       // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
+                                       self.load( self.anchors.index( this ) );
+
+                                       this.blur();
+                                       return false;
+                               }
+                       }
+
+                       if ( o.cookie ) {
+                               self._cookie( o.selected, o.cookie );
+                       }
+
+                       // show new tab
+                       if ( $show.length ) {
+                               if ( $hide.length ) {
+                                       self.element.queue( "tabs", function() {
+                                               hideTab( el, $hide );
+                                       });
+                               }
+                               self.element.queue( "tabs", function() {
+                                       showTab( el, $show );
+                               });
+
+                               self.load( self.anchors.index( this ) );
+                       } else {
+                               throw "jQuery UI Tabs: Mismatching fragment identifier.";
+                       }
+
+                       // Prevent IE from keeping other link focussed when using the back button
+                       // and remove dotted border from clicked link. This is controlled via CSS
+                       // in modern browsers; blur() removes focus from address bar in Firefox
+                       // which can become a usability and annoying problem with tabs('rotate').
+                       if ( $.browser.msie ) {
+                               this.blur();
+                       }
+               });
+
+               // disable click in any case
+               this.anchors.bind( "click.tabs", function(){
+                       return false;
+               });
+       },
+
+    _getIndex: function( index ) {
+               // meta-function to give users option to provide a href string instead of a numerical index.
+               // also sanitizes numerical indexes to valid values.
+               if ( typeof index == "string" ) {
+                       index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
+               }
+
+               return index;
+       },
+
+       destroy: function() {
+               var o = this.options;
+
+               this.abort();
+
+               this.element
+                       .unbind( ".tabs" )
+                       .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
+                       .removeData( "tabs" );
+
+               this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
+
+               this.anchors.each(function() {
+                       var href = $.data( this, "href.tabs" );
+                       if ( href ) {
+                               this.href = href;
+                       }
+                       var $this = $( this ).unbind( ".tabs" );
+                       $.each( [ "href", "load", "cache" ], function( i, prefix ) {
+                               $this.removeData( prefix + ".tabs" );
+                       });
+               });
+
+               this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
+                       if ( $.data( this, "destroy.tabs" ) ) {
+                               $( this ).remove();
+                       } else {
+                               $( this ).removeClass([
+                                       "ui-state-default",
+                                       "ui-corner-top",
+                                       "ui-tabs-selected",
+                                       "ui-state-active",
+                                       "ui-state-hover",
+                                       "ui-state-focus",
+                                       "ui-state-disabled",
+                                       "ui-tabs-panel",
+                                       "ui-widget-content",
+                                       "ui-corner-bottom",
+                                       "ui-tabs-hide"
+                               ].join( " " ) );
+                       }
+               });
+
+               if ( o.cookie ) {
+                       this._cookie( null, o.cookie );
+               }
+
+               return this;
+       },
+
+       add: function( url, label, index ) {
+               if ( index === undefined ) {
+                       index = this.anchors.length;
+               }
+
+               var self = this,
+                       o = this.options,
+                       $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
+                       id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
+
+               $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
+
+               // try to find an existing element before creating a new one
+               var $panel = self.element.find( "#" + id );
+               if ( !$panel.length ) {
+                       $panel = $( o.panelTemplate )
+                               .attr( "id", id )
+                               .data( "destroy.tabs", true );
+               }
+               $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
+
+               if ( index >= this.lis.length ) {
+                       $li.appendTo( this.list );
+                       $panel.appendTo( this.list[ 0 ].parentNode );
+               } else {
+                       $li.insertBefore( this.lis[ index ] );
+                       $panel.insertBefore( this.panels[ index ] );
+               }
+
+               o.disabled = $.map( o.disabled, function( n, i ) {
+                       return n >= index ? ++n : n;
+               });
+
+               this._tabify();
+
+               if ( this.anchors.length == 1 ) {
+                       o.selected = 0;
+                       $li.addClass( "ui-tabs-selected ui-state-active" );
+                       $panel.removeClass( "ui-tabs-hide" );
+                       this.element.queue( "tabs", function() {
+                               self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
+                       });
+
+                       this.load( 0 );
+               }
+
+               this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
+               return this;
+       },
+
+       remove: function( index ) {
+               index = this._getIndex( index );
+               var o = this.options,
+                       $li = this.lis.eq( index ).remove(),
+                       $panel = this.panels.eq( index ).remove();
+
+               // If selected tab was removed focus tab to the right or
+               // in case the last tab was removed the tab to the left.
+               if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
+                       this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
+               }
+
+               o.disabled = $.map(
+                       $.grep( o.disabled, function(n, i) {
+                               return n != index;
+                       }),
+                       function( n, i ) {
+                               return n >= index ? --n : n;
+                       });
+
+               this._tabify();
+
+               this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
+               return this;
+       },
+
+       enable: function( index ) {
+               index = this._getIndex( index );
+               var o = this.options;
+               if ( $.inArray( index, o.disabled ) == -1 ) {
+                       return;
+               }
+
+               this.lis.eq( index ).removeClass( "ui-state-disabled" );
+               o.disabled = $.grep( o.disabled, function( n, i ) {
+                       return n != index;
+               });
+
+               this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
+               return this;
+       },
+
+       disable: function( index ) {
+               index = this._getIndex( index );
+               var self = this, o = this.options;
+               // cannot disable already selected tab
+               if ( index != o.selected ) {
+                       this.lis.eq( index ).addClass( "ui-state-disabled" );
+
+                       o.disabled.push( index );
+                       o.disabled.sort();
+
+                       this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
+               }
+
+               return this;
+       },
+
+       select: function( index ) {
+               index = this._getIndex( index );
+               if ( index == -1 ) {
+                       if ( this.options.collapsible && this.options.selected != -1 ) {
+                               index = this.options.selected;
+                       } else {
+                               return this;
+                       }
+               }
+               this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
+               return this;
+       },
+
+       load: function( index ) {
+               index = this._getIndex( index );
+               var self = this,
+                       o = this.options,
+                       a = this.anchors.eq( index )[ 0 ],
+                       url = $.data( a, "load.tabs" );
+
+               this.abort();
+
+               // not remote or from cache
+               if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
+                       this.element.dequeue( "tabs" );
+                       return;
+               }
+
+               // load remote from here on
+               this.lis.eq( index ).addClass( "ui-state-processing" );
+
+               if ( o.spinner ) {
+                       var span = $( "span", a );
+                       span.data( "label.tabs", span.html() ).html( o.spinner );
+               }
+
+               this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
+                       url: url,
+                       success: function( r, s ) {
+                               self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
+
+                               // take care of tab labels
+                               self._cleanup();
+
+                               if ( o.cache ) {
+                                       $.data( a, "cache.tabs", true );
+                               }
+
+                               self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
+                               try {
+                                       o.ajaxOptions.success( r, s );
+                               }
+                               catch ( e ) {}
+                       },
+                       error: function( xhr, s, e ) {
+                               // take care of tab labels
+                               self._cleanup();
+
+                               self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
+                               try {
+                                       // Passing index avoid a race condition when this method is
+                                       // called after the user has selected another tab.
+                                       // Pass the anchor that initiated this request allows
+                                       // loadError to manipulate the tab content panel via $(a.hash)
+                                       o.ajaxOptions.error( xhr, s, index, a );
+                               }
+                               catch ( e ) {}
+                       }
+               } ) );
+
+               // last, so that load event is fired before show...
+               self.element.dequeue( "tabs" );
+
+               return this;
+       },
+
+       abort: function() {
+               // stop possibly running animations
+               this.element.queue( [] );
+               this.panels.stop( false, true );
+
+               // "tabs" queue must not contain more than two elements,
+               // which are the callbacks for the latest clicked tab...
+               this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
+
+               // terminate pending requests from other tabs
+               if ( this.xhr ) {
+                       this.xhr.abort();
+                       delete this.xhr;
+               }
+
+               // take care of tab labels
+               this._cleanup();
+               return this;
+       },
+
+       url: function( index, url ) {
+               this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
+               return this;
+       },
+
+       length: function() {
+               return this.anchors.length;
+       }
+});
+
+$.extend( $.ui.tabs, {
+       version: "1.8.12"
+});
+
+/*
+ * Tabs Extensions
+ */
+
+/*
+ * Rotate
+ */
+$.extend( $.ui.tabs.prototype, {
+       rotation: null,
+       rotate: function( ms, continuing ) {
+               var self = this,
+                       o = this.options;
+
+               var rotate = self._rotate || ( self._rotate = function( e ) {
+                       clearTimeout( self.rotation );
+                       self.rotation = setTimeout(function() {
+                               var t = o.selected;
+                               self.select( ++t < self.anchors.length ? t : 0 );
+                       }, ms );
+                       
+                       if ( e ) {
+                               e.stopPropagation();
+                       }
+               });
+
+               var stop = self._unrotate || ( self._unrotate = !continuing
+                       ? function(e) {
+                               if (e.clientX) { // in case of a true click
+                                       self.rotate(null);
+                               }
+                       }
+                       : function( e ) {
+                               t = o.selected;
+                               rotate();
+                       });
+
+               // start rotation
+               if ( ms ) {
+                       this.element.bind( "tabsshow", rotate );
+                       this.anchors.bind( o.event + ".tabs", stop );
+                       rotate();
+               // stop rotation
+               } else {
+                       clearTimeout( self.rotation );
+                       this.element.unbind( "tabsshow", rotate );
+                       this.anchors.unbind( o.event + ".tabs", stop );
+                       delete this._rotate;
+                       delete this._unrotate;
+               }
+
+               return this;
+       }
+});
+
+})( jQuery );
+/*
+ * jQuery Tooltip plugin 1.3
+ *
+ * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
+ * http://docs.jquery.com/Plugins/Tooltip
+ *
+ * Copyright (c) 2006 - 2008 Jörn Zaefferer
+ *
+ * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
+ * 
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ */
+;(function($) {
+       
+               // the tooltip element
+       var helper = {},
+               // the current tooltipped element
+               current,
+               // the title of the current element, used for restoring
+               title,
+               // timeout id for delayed tooltips
+               tID,
+               // IE 5.5 or 6
+               IE = $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),
+               // flag for mouse tracking
+               track = false;
+       
+       $.tooltip = {
+               blocked: false,
+               defaults: {
+                       delay: 200,
+                       fade: false,
+                       showURL: true,
+                       extraClass: "",
+                       top: 15,
+                       left: 15,
+                       id: "tooltip"
+               },
+               block: function() {
+                       $.tooltip.blocked = !$.tooltip.blocked;
+               }
+       };
+       
+       $.fn.extend({
+               tooltip: function(settings) {
+                       settings = $.extend({}, $.tooltip.defaults, settings);
+                       createHelper(settings);
+                       return this.each(function() {
+                                       $.data(this, "tooltip", settings);
+                                       this.tOpacity = helper.parent.css("opacity");
+                                       // copy tooltip into its own expando and remove the title
+                                       this.tooltipText = this.title;
+                                       $(this).removeAttr("title");
+                                       // also remove alt attribute to prevent default tooltip in IE
+                                       this.alt = "";
+                               })
+                               .mouseover(save)
+                               .mouseout(hide)
+                               .click(hide);
+               },
+               fixPNG: IE ? function() {
+                       return this.each(function () {
+                               var image = $(this).css('backgroundImage');
+                               if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
+                                       image = RegExp.$1;
+                                       $(this).css({
+                                               'backgroundImage': 'none',
+                                               'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
+                                       }).each(function () {
+                                               var position = $(this).css('position');
+                                               if (position != 'absolute' && position != 'relative')
+                                                       $(this).css('position', 'relative');
+                                       });
+                               }
+                       });
+               } : function() { return this; },
+               unfixPNG: IE ? function() {
+                       return this.each(function () {
+                               $(this).css({'filter': '', backgroundImage: ''});
+                       });
+               } : function() { return this; },
+               hideWhenEmpty: function() {
+                       return this.each(function() {
+                               $(this)[ $(this).html() ? "show" : "hide" ]();
+                       });
+               },
+               url: function() {
+                       return this.attr('href') || this.attr('src');
+               }
+       });
+       
+       function createHelper(settings) {
+               // there can be only one tooltip helper
+               if( helper.parent )
+                       return;
+               // create the helper, h3 for title, div for url
+               helper.parent = $('<div id="' + settings.id + '"><h3></h3><div class="body"></div><div class="url"></div></div>')
+                       // add to document
+                       .appendTo(document.body)
+                       // hide it at first
+                       .hide();
+                       
+               // apply bgiframe if available
+               if ( $.fn.bgiframe )
+                       helper.parent.bgiframe();
+               
+               // save references to title and url elements
+               helper.title = $('h3', helper.parent);
+               helper.body = $('div.body', helper.parent);
+               helper.url = $('div.url', helper.parent);
+       }
+       
+       function settings(element) {
+               return $.data(element, "tooltip");
+       }
+       
+       // main event handler to start showing tooltips
+       function handle(event) {
+               // show helper, either with timeout or on instant
+               if( settings(this).delay )
+                       tID = setTimeout(show, settings(this).delay);
+               else
+                       show();
+               
+               // if selected, update the helper position when the mouse moves
+               track = !!settings(this).track;
+               $(document.body).bind('mousemove', update);
+                       
+               // update at least once
+               update(event);
+       }
+       
+       // save elements title before the tooltip is displayed
+       function save() {
+               // if this is the current source, or it has no title (occurs with click event), stop
+               if ( $.tooltip.blocked || this == current || (!this.tooltipText && !settings(this).bodyHandler) )
+                       return;
+
+               // save current
+               current = this;
+               title = this.tooltipText;
+               
+               if ( settings(this).bodyHandler ) {
+                       helper.title.hide();
+                       var bodyContent = settings(this).bodyHandler.call(this);
+                       if (bodyContent.nodeType || bodyContent.jquery) {
+                               helper.body.empty().append(bodyContent)
+                       } else {
+                               helper.body.html( bodyContent );
+                       }
+                       helper.body.show();
+               } else if ( settings(this).showBody ) {
+                       var parts = title.split(settings(this).showBody);
+                       helper.title.html(parts.shift()).show();
+                       helper.body.empty();
+                       for(var i = 0, part; (part = parts[i]); i++) {
+                               if(i > 0)
+                                       helper.body.append("<br/>");
+                               helper.body.append(part);
+                       }
+                       helper.body.hideWhenEmpty();
+               } else {
+                       helper.title.html(title).show();
+                       helper.body.hide();
+               }
+               
+               // if element has href or src, add and show it, otherwise hide it
+               if( settings(this).showURL && $(this).url() )
+                       helper.url.html( $(this).url().replace('http://', '') ).show();
+               else 
+                       helper.url.hide();
+               
+               // add an optional class for this tip
+               helper.parent.addClass(settings(this).extraClass);
+
+               // fix PNG background for IE
+               if (settings(this).fixPNG )
+                       helper.parent.fixPNG();
+                       
+               handle.apply(this, arguments);
+       }
+       
+       // delete timeout and show helper
+       function show() {
+               tID = null;
+               if ((!IE || !$.fn.bgiframe) && settings(current).fade) {
+                       if (helper.parent.is(":animated"))
+                               helper.parent.stop().show().fadeTo(settings(current).fade, current.tOpacity);
+                       else
+                               helper.parent.is(':visible') ? helper.parent.fadeTo(settings(current).fade, current.tOpacity) : helper.parent.fadeIn(settings(current).fade);
+               } else {
+                       helper.parent.show();
+               }
+               update();
+       }
+       
+       /**
+        * callback for mousemove
+        * updates the helper position
+        * removes itself when no current element
+        */
+       function update(event)  {
+               if($.tooltip.blocked)
+                       return;
+               
+               if (event && event.target.tagName == "OPTION") {
+                       return;
+               }
+               
+               // stop updating when tracking is disabled and the tooltip is visible
+               if ( !track && helper.parent.is(":visible")) {
+                       $(document.body).unbind('mousemove', update)
+               }
+               
+               // if no current element is available, remove this listener
+               if( current == null ) {
+                       $(document.body).unbind('mousemove', update);
+                       return; 
+               }
+               
+               // remove position helper classes
+               helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");
+               
+               var left = helper.parent[0].offsetLeft;
+               var top = helper.parent[0].offsetTop;
+               if (event) {
+                       // position the helper 15 pixel to bottom right, starting from mouse position
+                       left = event.pageX + settings(current).left;
+                       top = event.pageY + settings(current).top;
+                       var right='auto';
+                       if (settings(current).positionLeft) {
+                               right = $(window).width() - left;
+                               left = 'auto';
+                       }
+                       helper.parent.css({
+                               left: left,
+                               right: right,
+                               top: top
+                       });
+               }
+               
+               var v = viewport(),
+                       h = helper.parent[0];
+               // check horizontal position
+               if (v.x + v.cx < h.offsetLeft + h.offsetWidth) {
+                       left -= h.offsetWidth + 20 + settings(current).left;
+                       helper.parent.css({left: left + 'px'}).addClass("viewport-right");
+               }
+               // check vertical position
+               if (v.y + v.cy < h.offsetTop + h.offsetHeight) {
+                       top -= h.offsetHeight + 20 + settings(current).top;
+                       helper.parent.css({top: top + 'px'}).addClass("viewport-bottom");
+               }
+       }
+       
+       function viewport() {
+               return {
+                       x: $(window).scrollLeft(),
+                       y: $(window).scrollTop(),
+                       cx: $(window).width(),
+                       cy: $(window).height()
+               };
+       }
+       
+       // hide helper and restore added classes and the title
+       function hide(event) {
+               if($.tooltip.blocked)
+                       return;
+               // clear timeout if possible
+               if(tID)
+                       clearTimeout(tID);
+               // no more current element
+               current = null;
+               
+               var tsettings = settings(this);
+               function complete() {
+                       helper.parent.removeClass( tsettings.extraClass ).hide().css("opacity", "");
+               }
+               if ((!IE || !$.fn.bgiframe) && tsettings.fade) {
+                       if (helper.parent.is(':animated'))
+                               helper.parent.stop().fadeTo(tsettings.fade, 0, complete);
+                       else
+                               helper.parent.stop().fadeOut(tsettings.fade, complete);
+               } else
+                       complete();
+               
+               if( settings(this).fixPNG )
+                       helper.parent.unfixPNG();
+       }
+       
+})(jQuery);
+/*!
+Math.uuid.js (v1.4)
+http://www.broofa.com
+mailto:robert@broofa.com
+
+Copyright (c) 2010 Robert Kieffer
+Dual licensed under the MIT and GPL licenses.
+*/
+
+/*
+ * Generate a random uuid.
+ *
+ * USAGE: Math.uuid(length, radix)
+ *   length - the desired number of characters
+ *   radix  - the number of allowable values for each character.
+ *
+ * EXAMPLES:
+ *   // No arguments  - returns RFC4122, version 4 ID
+ *   >>> Math.uuid()
+ *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
+ *
+ *   // One argument - returns ID of the specified length
+ *   >>> Math.uuid(15)     // 15 character ID (default base=62)
+ *   "VcydxgltxrVZSTV"
+ *
+ *   // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62)
+ *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
+ *   "01001010"
+ *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
+ *   "47473046"
+ *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
+ *   "098F4D35"
+ */
+(function() {
+  // Private array of chars to use
+  var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
+
+  Math.uuid = function (len, radix) {
+    var chars = CHARS, uuid = [], i;
+    radix = radix || chars.length;
+
+    if (len) {
+      // Compact form
+      for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
+    } else {
+      // rfc4122, version 4 form
+      var r;
+
+      // rfc4122 requires these characters
+      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
+      uuid[14] = '4';
+
+      // Fill in random data.  At i==19 set the high bits of clock sequence as
+      // per rfc4122, sec. 4.1.5
+      for (i = 0; i < 36; i++) {
+        if (!uuid[i]) {
+          r = 0 | Math.random()*16;
+          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
+        }
+      }
+    }
+
+    return uuid.join('');
+  };
+
+  // A more performant, but slightly bulkier, RFC4122v4 solution.  We boost performance
+  // by minimizing calls to random()
+  Math.uuidFast = function() {
+    var chars = CHARS, uuid = new Array(36), rnd=0, r;
+    for (var i = 0; i < 36; i++) {
+      if (i==8 || i==13 ||  i==18 || i==23) {
+        uuid[i] = '-';
+      } else if (i==14) {
+        uuid[i] = '4';
+      } else {
+        if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0;
+        r = rnd & 0xf;
+        rnd = rnd >> 4;
+        uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
+      }
+    }
+    return uuid.join('');
+  };
+
+  // A more compact, but less performant, RFC4122v4 solution:
+  Math.uuidCompact = function() {
+    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+      var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+      return v.toString(16);
+    });
+  };
+})();
+// jXHR.js (JSON-P XHR)\r
+// v0.1 (c) Kyle Simpson\r
+// MIT License\r
+\r
+(function(global){\r
+       var SETTIMEOUT = global.setTimeout, // for better compression\r
+               doc = global.document,\r
+               callback_counter = 0;\r
+               \r
+       global.jXHR = function() {\r
+               var script_url,\r
+                       script_loaded,\r
+                       jsonp_callback,\r
+                       scriptElem,\r
+                       publicAPI = null;\r
+                       \r
+               function removeScript() { try { scriptElem.parentNode.removeChild(scriptElem); } catch (err) { } }\r
+                       \r
+               function reset() {\r
+                       script_loaded = false;\r
+                       script_url = "";\r
+                       removeScript();\r
+                       scriptElem = null;\r
+                       fireReadyStateChange(0);\r
+               }\r
+               \r
+               function ThrowError(msg) {\r
+                       try { publicAPI.onerror.call(publicAPI,msg,script_url); } catch (err) { throw new Error(msg); }\r
+               }\r
+\r
+               function handleScriptLoad() {\r
+                       if ((this.readyState && this.readyState!=="complete" && this.readyState!=="loaded") || script_loaded) { return; }\r
+                       this.onload = this.onreadystatechange = null; // prevent memory leak\r
+                       script_loaded = true;\r
+                       if (publicAPI.readyState !== 4) ThrowError("Script failed to load ["+script_url+"].");\r
+                       removeScript();\r
+               }\r
+               \r
+               function fireReadyStateChange(rs,args) {\r
+                       args = args || [];\r
+                       publicAPI.readyState = rs;\r
+                       if (typeof publicAPI.onreadystatechange === "function") publicAPI.onreadystatechange.apply(publicAPI,args);\r
+               }\r
+                               \r
+               publicAPI = {\r
+                       onerror:null,\r
+                       onreadystatechange:null,\r
+                       readyState:0,\r
+                       open:function(method,url){\r
+                               reset();\r
+                               internal_callback = "cb"+(callback_counter++);\r
+                               (function(icb){\r
+                                       global.jXHR[icb] = function() {\r
+                                               try { fireReadyStateChange.call(publicAPI,4,arguments); } \r
+                                               catch(err) { \r
+                                                       publicAPI.readyState = -1;\r
+                                                       ThrowError("Script failed to run ["+script_url+"]."); \r
+                                               }\r
+                                               global.jXHR[icb] = null;\r
+                                       };\r
+                               })(internal_callback);\r
+                               script_url = url.replace(/=\?/,"=jXHR."+internal_callback);\r
+                               fireReadyStateChange(1);\r
+                       },\r
+                       send:function(){\r
+                               SETTIMEOUT(function(){\r
+                                       scriptElem = doc.createElement("script");\r
+                                       scriptElem.setAttribute("type","text/javascript");\r
+                                       scriptElem.onload = scriptElem.onreadystatechange = function(){handleScriptLoad.call(scriptElem);};\r
+                                       scriptElem.setAttribute("src",script_url);\r
+                                       doc.getElementsByTagName("head")[0].appendChild(scriptElem);\r
+                               },0);\r
+                               fireReadyStateChange(2);\r
+                       },\r
+                       setRequestHeader:function(){}, // noop\r
+                       getResponseHeader:function(){return "";}, // basically noop\r
+                       getAllResponseHeaders:function(){return [];} // ditto\r
+               };\r
+\r
+               reset();\r
+               \r
+               return publicAPI;\r
+       };\r
+})(window);//////////////////////////////////////////////////////////////////////////////
+//                                                                          //
+// Wii Opera SDK - 3D Math Class v2.7.22 2008-12-14                         //
+// (c) 2007-2008 Daniel Gump. All Rights Reserved.                          //
+// http://wiioperasdk.com, http://hullbreachonline.com                      //
+// hullbreach@hullbreachonline.com                                          //
+//                                                                          //
+//  Wii is a trademark of Nintendo Co., Ltd.                                //
+//  Opera is a trademark of Opera, ASA.                                     //
+//  This software package is not associated with either company             //
+//  but was created to support users of both.  Its alternative name         //
+//  when supporting other products is the HULLBREACH SDK.                   //
+//                                                                          //
+//  Redistribution and use in source and binary forms, with or without      //
+//  modification, are permitted provided that the following conditions      //
+//  are met:                                                                //
+//    * Redistributions of source code must retain the above copyright      //
+//      notice, this list of conditions and the following disclaimer.       //
+//    * Redistributions in binary form must reproduce the above copyright   //
+//      notice, this list of conditions and the following disclaimer in     //
+//      the documentation and/or other materials provided with the          //
+//      distribution.                                                       //
+//    * Neither the names HULLBREACH ONLINE nor WII OPERA SDK nor the names //
+//      of its contributors may be used to endorse or promote products      //
+//      derived from this software without specific prior written           //
+//      permission.                                                         //
+//    * If the explicit purpose of the software is not to support the       //
+//      Nintendo Wii or the Opera Web browser, then the names of such must  //
+//      not be used in any derived product. The name shall be the           //
+//      HULLBREACH SDK with a reference link to http://hullbreachonline.    //
+//                                                                          //
+//  THIS SOFTWARE IS PROVIDED BY Daniel Gump ''AS IS'' AND ANY EXPRESS OR   //
+//  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          //
+//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  //
+//  DISCLAIMED. IN NO EVENT SHALL Daniel Gump BE LIABLE FOR ANY DIRECT,     //
+//  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      //
+//  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      //
+//  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      //
+//  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     //
+//  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   //
+//  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      //
+//  POSSIBILITY OF SUCH DAMAGE.                                             //
+//////////////////////////////////////////////////////////////////////////////
+
+function ThreeD(){
+       POLYMESH = new Array();
+
+       CENTERX = 400; CENTERY = 240;
+       LIGHTX = -1000; LIGHTY = -1000; LIGHTZ = -1000;
+       ORIGINX = 0; ORIGINY = 0; ORIGINZ = 0;
+       ANGLEX = 0; ANGLEY = 0; ANGLEZ = 0;
+}
+
+ThreeD.prototype.setPoints = function(Points){
+       POLYMESH = [];
+       for(var value=Points.length;--value>=0;) POLYMESH[value] = Points[value].slice();
+}
+ThreeD.prototype.loadMesh = function(array){
+       if(POLYMESH = array.split(";")) for(i=POLYMESH.length;--i>=0;) POLYMESH[i] = POLYMESH[i].split(",");
+}
+ThreeD.prototype.getPoints = function(){ return POLYMESH; }
+
+ThreeD.prototype.setCenter = function(x,y){ CENTERX = x|0; CENTERY = y|0; }
+ThreeD.prototype.setLight = function(x,y,z){ LIGHTX = x|0; LIGHTY = y|0; LIGHTZ = z|0; }
+
+ThreeD.prototype.explode = function(z){
+       var x1, y1, z1, x2, y2, z2;
+       var normali, normalj, normalk, magNormal;
+
+       for(var value=POLYMESH.length;--value>=0;){
+               x1 = POLYMESH[value][3]-POLYMESH[value][0]; y1 = POLYMESH[value][4]-POLYMESH[value][1]; z1 = POLYMESH[value][5]-POLYMESH[value][2]; 
+               x2 = POLYMESH[value][6]-POLYMESH[value][0]; y2 = POLYMESH[value][7]-POLYMESH[value][1]; z2 = POLYMESH[value][8]-POLYMESH[value][2]; 
+
+               normali = y2*z1-y1*z2; normalj = x1*z2-x2*z1; normalk = x2*y1-x1*y2;
+               magNormal = z/Math.sqrt(normali*normali+normalj*normalj+normalk*normalk);
+
+               var movex = -normali*magNormal|0;
+               var movey = -normalj*magNormal|0;
+               var movez = -normalk*magNormal|0;
+
+               POLYMESH[value][0] += movex; POLYMESH[value][1] += movey; POLYMESH[value][2] += movez;
+               POLYMESH[value][3] += movex; POLYMESH[value][4] += movey; POLYMESH[value][5] += movez;
+               POLYMESH[value][6] += movex; POLYMESH[value][7] += movey; POLYMESH[value][8] += movez;
+       }
+}
+ThreeD.prototype.normalMap = function(normalMap){
+       var x1, y1, z1, x2, y2, z2;
+       var normali, normalj, normalk, magNormal;
+
+       for(var value=POLYMESH.length;--value>=0;){
+               x1 = POLYMESH[value][3]-POLYMESH[value][0]; y1 = POLYMESH[value][4]-POLYMESH[value][1]; z1 = POLYMESH[value][5]-POLYMESH[value][2]; 
+               x2 = POLYMESH[value][6]-POLYMESH[value][0]; y2 = POLYMESH[value][7]-POLYMESH[value][1]; z2 = POLYMESH[value][8]-POLYMESH[value][2]; 
+
+               normali = y2*z1-y1*z2; normalj = x1*z2-x2*z1; normalk = x2*y1-x1*y2;
+               normal = 1/Math.sqrt(normali*normali+normalj*normalj+normalk*normalk);
+               
+               for(index2=0; index2<4; index2++){
+                       for(index=0; index<=index2; index++){
+                               magNormal = normalMap[index][index2]*normal|0;
+
+                               var movex = -normali*magNormal;
+                               var movey = -normalj*magNormal;
+                               var movez = -normalk*magNormal;
+                               
+                               POLYMESH[POLYMESH.length] = new Array(POLYMESH[value][0]+movex,POLYMESH[value][1]+movey,POLYMESH[value][2]+movez,
+                                                       POLYMESH[value][3]+movex,POLYMESH[value][4]+movey,POLYMESH[value][7]+movez,
+                                                       POLYMESH[value][6]+movex,POLYMESH[value][7]+movey,POLYMESH[value][8]+movez,
+                                                       POLYMESH[value][9],POLYMESH[value][10],POLYMESH[value][11],
+                                                       POLYMESH[value][12],POLYMESH[value][13], true, index, index2);
+                       }
+               }
+       }
+}
+ThreeD.prototype.move = function(x,y,z){
+       for(var value=POLYMESH.length;--value>=0;)
+               for(var point=-1;++point<3;){
+                       POLYMESH[value][point*3+2] += z;
+                       POLYMESH[value][point*3+1] += y;
+                       POLYMESH[value][point*3] += x;
+               }
+}
+ThreeD.prototype.rotate = function(anglex,angley,anglez){
+       var cosx = Math.cos(anglex*0.01745329); var sinx = Math.sin(anglex*0.01745329);
+       var cosy = Math.cos(angley*0.01745329); var siny = Math.sin(angley*0.01745329);
+       var cosz = Math.cos(anglez*0.01745329); var sinz = Math.sin(anglez*0.01745329);
+
+       for(var value=POLYMESH.length;--value>=0;)
+               for(var point=-1;++point<3;){
+                       var tempz = sinx*POLYMESH[value][point*3+1]+cosx*POLYMESH[value][point*3+2];
+                       var tempy = cosx*POLYMESH[value][point*3+1]-sinx*POLYMESH[value][point*3+2];
+                       var tempx = cosy*POLYMESH[value][point*3]+siny*tempz;
+                       POLYMESH[value][point*3+2] = cosy*tempz-siny*POLYMESH[value][point*3];
+                       POLYMESH[value][point*3+1] = sinz*tempx+cosz*tempy;
+                       POLYMESH[value][point*3] = cosz*tempx-sinz*tempy;
+               }
+}
+ThreeD.prototype.scale = function(scalex,scaley,scalez){
+       for(var value=POLYMESH.length;--value>=0;)
+               for(var point=-1;++point<3;){
+                       POLYMESH[value][point*3+2] *= scalex;
+                       POLYMESH[value][point*3+1] *= scaley;
+                       POLYMESH[value][point*3] *= scalez;
+               }
+}
+
+ThreeD.prototype.backface = function(){
+       for(var value=POLYMESH.length, newvalue=0, TempPOLYMESH = [];--value>=0;)
+               if((POLYMESH[value][3]-POLYMESH[value][0])*(POLYMESH[value][7]-POLYMESH[value][1])-(POLYMESH[value][6]-POLYMESH[value][0])*(POLYMESH[value][4]-POLYMESH[value][1])>0){
+                       TempPOLYMESH[newvalue++] = POLYMESH[value].slice();
+               }
+       POLYMESH = TempPOLYMESH;
+}
+ThreeD.prototype.zSort = function(){ POLYMESH.sort(function(b,a){return b[2]+b[5]+b[8]-a[2]-a[5]-a[8]}); }
+
+ThreeD.prototype.fade = function(bright){
+       for(var value=POLYMESH.length;--value>=0;) POLYMESH[value][13] += bright;
+}
+ThreeD.prototype.shade = function(){
+       var x1, y1, z1, x2, y2, z2;
+       var normali, normalj, normalk, magNormal;
+       var lighti, lightj, lightk, magLight;
+
+       for(var value=POLYMESH.length;--value>=0;){
+               x1 = POLYMESH[value][3]-POLYMESH[value][0]; y1 = POLYMESH[value][4]-POLYMESH[value][1]; z1 = POLYMESH[value][5]-POLYMESH[value][2]; 
+               x2 = POLYMESH[value][6]-POLYMESH[value][0]; y2 = POLYMESH[value][7]-POLYMESH[value][1]; z2 = POLYMESH[value][8]-POLYMESH[value][2]; 
+
+               normali = y1*z2-y2*z1; normalj = x2*z1-x1*z2; normalk = x1*y2-x2*y1;
+
+               lighti = LIGHTX-(POLYMESH[value][0]+POLYMESH[value][3]+POLYMESH[value][6])*0.33333333333333333;
+               lightj = LIGHTY-(POLYMESH[value][1]+POLYMESH[value][4]+POLYMESH[value][7])*0.33333333333333333;
+               lightk = LIGHTZ-(POLYMESH[value][2]+POLYMESH[value][5]+POLYMESH[value][8])*0.33333333333333333;
+
+               POLYMESH[value][13] = 2*(normali*lighti + normalj*lightj + normalk*lightk)/Math.sqrt((normali*normali+normalj*normalj+normalk*normalk)*(lighti*lighti+lightj*lightj+lightk*lightk))-1;
+       }
+}
+ThreeD.prototype.reColor = function(r,g,b){
+       r=r>255?255:(r<0?0:r|0);
+       g=g>255?255:(g<0?0:g|0);
+       b=b>255?255:(b<0?0:b|0);
+       for(var value=POLYMESH.length;--value>=0;){
+               POLYMESH[value][9]=r;
+               POLYMESH[value][10]=g;
+               POLYMESH[value][11]=b;
+       }
+}
+ThreeD.prototype.shadow = function(){
+       rayorigins = []; 
+       raynormals = [];
+       edge1 = [];
+       edge2 = [];
+
+       for(var value=0, normali, normalj, normalk, magNormal;value<POLYMESH.length;value++){
+               edge1[value] = new Array(POLYMESH[value][3]-POLYMESH[value][0], POLYMESH[value][4]-POLYMESH[value][1], POLYMESH[value][5]-POLYMESH[value][2]);
+               edge2[value] = new Array(POLYMESH[value][6]-POLYMESH[value][0], POLYMESH[value][7]-POLYMESH[value][1], POLYMESH[value][8]-POLYMESH[value][2]);
+
+               rayorigins[value] = new Array((POLYMESH[value][0]+POLYMESH[value][3]+POLYMESH[value][6])*0.33333333333333333, (POLYMESH[value][1]+POLYMESH[value][4]+POLYMESH[value][7])*0.33333333333333333, (POLYMESH[value][2]+POLYMESH[value][5]+POLYMESH[value][8])*0.33333333333333333);
+
+               normali = LIGHTX-rayorigins[value][0];
+               normalj = LIGHTY-rayorigins[value][1];
+               normalk = LIGHTZ-rayorigins[value][2];
+               magNormal = 1/Math.sqrt(normali*normali+normalj*normalj+normalk*normalk);
+               raynormals[value] = new Array(normali*magNormal, normalj*magNormal, normalk*magNormal);
+       }
+
+       for(var value=POLYMESH.length;--value>=0;){
+               for(var value2=POLYMESH.length;--value2>=0;){
+                       if(value2!=value){
+                               var pvecti = raynormals[value][1]*edge2[value2][2]-edge2[value2][1]*raynormals[value][2];
+                               var pvectj = edge2[value2][0]*raynormals[value][2]-raynormals[value][0]*edge2[value2][2];
+                               var pvectk = raynormals[value][0]*edge2[value2][1]-edge2[value2][0]*raynormals[value][1];
+
+                               if((det = edge1[value2][0]*pvecti+edge1[value2][1]*pvectj+edge1[value2][2]*pvectk)<0){
+                                       det=1/det;
+
+                                       var tvecti = rayorigins[value][0]-POLYMESH[value2][0];
+                                       var tvectj = rayorigins[value][1]-POLYMESH[value2][1];
+                                       var tvectk = rayorigins[value][2]-POLYMESH[value2][2];
+
+                                       if((u = (pvecti*tvecti+pvectj*tvectj+pvectk*tvectk) * det)>=0 && u<=1){
+                                               if((v = (raynormals[value][0]*(tvectj*edge1[value2][2]-edge1[value2][1]*tvectk)+raynormals[value][1]*(edge1[value2][0]*tvectk-tvecti*edge1[value2][2])+raynormals[value][2]*(tvecti*edge1[value2][1]-edge1[value2][0]*tvectj)) * det)>=0 && u+v<=1){
+                                                       POLYMESH[value][13] -=.5;
+                                                       break;
+                                               }
+                                       }
+                               }
+                               
+                       }
+               }
+       }
+}
+
+ThreeD.prototype.getTranslation = function(){
+       for(var value=POLYMESH.length,newvalue=0,TransPOLYMESH = [];--value>=0;){
+               var POLYMESH2=5000/(5000-POLYMESH[value][2]), POLYMESH5=5000/(5000-POLYMESH[value][5]), POLYMESH8=5000/(5000-POLYMESH[value][8]);
+               TransPOLYMESH[newvalue++] = new Array((CENTERX+POLYMESH[value][0]*POLYMESH2),(CENTERY+POLYMESH[value][1]*POLYMESH2),
+                                                                       (CENTERX+POLYMESH[value][3]*POLYMESH5),(CENTERY+POLYMESH[value][4]*POLYMESH5),
+                                                                       (CENTERX+POLYMESH[value][6]*POLYMESH8),(CENTERY+POLYMESH[value][7]*POLYMESH8),
+                                                                       POLYMESH[value][9]|0,POLYMESH[value][10]|0,POLYMESH[value][11]|0,POLYMESH[value][12]|0,POLYMESH[value][13]);
+       }
+       return TransPOLYMESH;
+}
+
+ThreeDee = new ThreeD();//////////////////////////////////////////////////////////////////////////////
+//                                                                          //
+// Wii Opera SDK - Drawing Class v2.6.16 2008-12-14                         //
+// (c) 2007-2008 Daniel Gump. All Rights Reserved.                          //
+// http://wiioperasdk.com, http://hullbreachonline.com                      //
+// hullbreach@hullbreachonline.com                                          //
+//                                                                          //
+//  Wii is a trademark of Nintendo Co., Ltd.                                //
+//  Opera is a trademark of Opera, ASA.                                     //
+//  This software package is not associated with either company             //
+//  but was created to support users of both.  Its alternative name         //
+//  when supporting other products is the HULLBREACH SDK.                   //
+//                                                                          //
+//  Redistribution and use in source and binary forms, with or without      //
+//  modification, are permitted provided that the following conditions      //
+//  are met:                                                                //
+//    * Redistributions of source code must retain the above copyright      //
+//      notice, this list of conditions and the following disclaimer.       //
+//    * Redistributions in binary form must reproduce the above copyright   //
+//      notice, this list of conditions and the following disclaimer in     //
+//      the documentation and/or other materials provided with the          //
+//      distribution.                                                       //
+//    * Neither the names HULLBREACH ONLINE nor WII OPERA SDK nor the names //
+//      of its contributors may be used to endorse or promote products      //
+//      derived from this software without specific prior written           //
+//      permission.                                                         //
+//    * If the explicit purpose of the software is not to support the       //
+//      Nintendo Wii or the Opera Web browser, then the names of such must  //
+//      not be used in any derived product. The name shall be the           //
+//      HULLBREACH SDK with a reference link to http://hullbreachonline.    //
+//                                                                          //
+//  THIS SOFTWARE IS PROVIDED BY Daniel Gump ''AS IS'' AND ANY EXPRESS OR   //
+//  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          //
+//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  //
+//  DISCLAIMED. IN NO EVENT SHALL Daniel Gump BE LIABLE FOR ANY DIRECT,     //
+//  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      //
+//  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      //
+//  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      //
+//  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     //
+//  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   //
+//  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      //
+//  POSSIBILITY OF SUCH DAMAGE.                                             //
+//////////////////////////////////////////////////////////////////////////////
+
+function Drawing(){
+       this.WIREFRAME = 1; this.FILL = 2;
+       ZOOM = 1;
+       CANVAS = null;
+       TEXTURES = null;
+}
+Drawing.prototype.initialize = function(canvas){
+       CANVAS = canvas.getContext("2d");
+       CANVAS.lineJoin = "round";
+       CANVAS.lineWidth = 1;
+}
+Drawing.prototype.loadTextures = function(textures){ TEXTURES = textures; }
+Drawing.prototype.setFillColor = function(r,g,b){ CANVAS.fillStyle = "rgb("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+")"; }
+Drawing.prototype.setFillColorA = function(r,g,b,a){ CANVAS.fillStyle = "rgba("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+", "+(a>255?1:(a<0?0:a/255))+")"; }
+Drawing.prototype.setLineColor = function(r,g,b){ CANVAS.strokeStyle = "rgb("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+")"; }
+Drawing.prototype.setLineColorA = function(r,g,b,a){ CANVAS.strokeStyle = "rgba("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+", "+(a>255?1:(a<0?0:a/255))+")"; }
+Drawing.prototype.clipCircle = function(centerx,centery,radius){ CANVAS.beginPath(); CANVAS.arc(centerx,centery,radius,0,6.28318531,false); CANVAS.clip(); }
+Drawing.prototype.clipRectangle = function(x1,y1,x2,y2){ CANVAS.beginPath(); CANVAS.strokeRect(x1,y1,x2-x1,y2-y1); CANVAS.clip(); }
+Drawing.prototype.drawCircle = function(centerx,centery,radius,style){
+       CANVAS.beginPath();
+       CANVAS.arc(centerx, centery, radius, 0, Math.PI*2, false);
+       if(style & this.FILL) CANVAS.fill();
+       if(style & this.WIREFRAME) CANVAS.stroke();
+}
+Drawing.prototype.drawImage = function(x1,y1,x2,y2,img,angle){
+       if(img.complete){
+               x1|=0;
+               y1|=0;
+               x2|=0;
+               y2|=0;
+               if(x2<x1) x2=x1+1;
+               if(y2<y1) y2=y1+1;
+               var centerx = (x1+x2)>>1;
+               var centery = (y1+y2)>>1;
+
+               CANVAS.save();
+               CANVAS.translate(centerx, centery);
+               if(angle) CANVAS.rotate(angle*0.01745329);
+               CANVAS.drawImage(img, x1-centerx, y1-centery, x2-x1, y2-y1);
+               CANVAS.restore();
+       }
+}
+Drawing.prototype.drawLine = function(x1, y1, x2, y2){ CANVAS.beginPath(); CANVAS.moveTo(x1|0, y1|0); CANVAS.lineTo(x2|0, y2|0); CANVAS.stroke(); }
+Drawing.prototype.drawRectangle = function(x1, y1, x2, y2, style, angle){
+       x1|=0;
+       y1|=0;
+       x2|=0;
+       y2|=0;
+       
+       if(!angle){
+               if(style & this.FILL) CANVAS.fillRect(x1, y1, x2-x1, y2-y1);
+               if(style & this.WIREFRAME) CANVAS.strokeRect(x1, y1, x2-x1, y2-y1);
+       }else{
+               var centerx = (x1+x2)>>1; var centery = (y1+y2)>>1;
+
+               CANVAS.save();
+               CANVAS.translate(centerx, centery);
+               CANVAS.rotate(angle*DEGTORAD);
+               if(style & this.FILL) CANVAS.fillRect(x1-centerx, y1-centery, x2-x1, y2-y1);
+               if(style & this.WIREFRAME) CANVAS.strokeRect(x1-centerx, y1-centery, x2-x1, y2-y1);
+               CANVAS.restore();
+       }
+}
+Drawing.prototype.drawScene = function(array,style){
+       var piOver2 = 1.570796326794897;
+       var piOver4 = 0.785398163397448;
+       var sqrt2half = 1.414213562373095;
+
+       for(tri=array.length;--tri>=0;){
+               var x1 = array[tri][0];
+               var y1 = array[tri][1];
+               var x2 = array[tri][2];
+               var y2 = array[tri][3];
+               var x3 = array[tri][4];
+               var y3 = array[tri][5];
+               shade=array[tri][10];
+
+               if(TEXTURES && array[tri][9]>=0){
+                       CANVAS.save();
+
+                       var u = (x2-x3)*(x2-x3)+(y2-y3)*(y2-y3);
+                       var v = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
+                       var w = (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
+
+                       var canvasRot = 0.5*Math.acos((w+v-u)/(2*Math.sqrt(w*v)));
+                       var scale = Math.cos(canvasRot)*sqrt2half;
+
+                       CANVAS.translate(x1,y1);
+                       CANVAS.rotate(Math.atan2(y2-y1,x2-x1)-piOver2+canvasRot);
+                       CANVAS.scale(Math.tan(canvasRot),1);
+                       CANVAS.rotate(piOver4);
+                       CANVAS.scale(Math.sqrt(w)*scale,Math.sqrt(v)*scale);
+                       //CANVAS.transform(x2-x1,y2-y1,x3-x1,y3-y1, x1,y1);
+                       CANVAS.drawImage((canvasimg = TEXTURES[array[tri][9]]), 0,0, canvasimg.width,canvasimg.height, 0,0, 1,1);
+                       CANVAS.restore();
+
+                       if(shade!=0){
+                               CANVAS.beginPath();
+                               CANVAS.moveTo(x1,y1);
+                               CANVAS.lineTo(x2,y2);
+                               CANVAS.lineTo(x3,y3);
+                               CANVAS.lineTo(x1,y1);
+                               if(shade>0){
+                                       if(shade>1) shade=1;
+                                       CANVAS.fillStyle = "rgba(255,255,255,"+(shade)+")";
+                                       CANVAS.strokeStyle = "rgba(255,255,255,"+(shade*.5)+")";
+                               }else if(shade<0){
+                                       if(shade<-1) shade=-1;
+                                       CANVAS.fillStyle = "rgba(0,0,0,"+(-shade)+")";
+                                       CANVAS.strokeStyle = "rgba(0,0,0,"+(-shade*.5)+")";
+                               }
+                               if(style & this.FILL) CANVAS.fill();
+                               if(style & this.WIREFRAME) CANVAS.stroke();
+                       }
+               }else{
+                       var red = array[tri][6];
+                       var green = array[tri][7];
+                       var blue = array[tri][8];
+                       if(shade!=0){
+                               red=(red*=++shade)>255?255:(red<0?0:red);
+                               green=(green*=shade)>255?255:(green<0?0:green);
+                               blue=(blue*=shade)>255?255:(blue<0?0:blue);
+                       }
+                       var color = "rgb("+(red|0)+","+(green|0)+","+(blue|0)+")";
+                       CANVAS.beginPath();
+                       CANVAS.moveTo(x1,y1);
+                       CANVAS.lineTo(x2,y2);
+                       CANVAS.lineTo(x3,y3);
+                       CANVAS.lineTo(x1,y1);
+                       if(style & this.FILL){ CANVAS.fillStyle = color; CANVAS.fill(); }
+                       if(style & this.WIREFRAME){ CANVAS.strokeStyle = color; CANVAS.stroke(); }
+               }
+       }
+}
+
+Drawing.prototype.drawFloor = function(x1,x2,y1,x3,x4,y2,img){
+       if((x2|=0)==(x1|=0)) x2++;
+       if((y2|=0)==(y1|=0)) y2++;
+       if((x4|=0)==(x3|=0)) x4++;
+       var absdy=(dy = y2-y1)<0?-dy:dy;
+
+       var sourceD = img.width-1, sourceY = (img.height-1)*(dx2 = x4-x3)/dy;
+       var destX = (x3-x1)/dy;
+       var tempY = 0;
+       var destW2 = (dx1 = x2-x1);
+
+       var absscale = (fullscale = 1.5*(dy>>31?-1:1)+dy/img.height)>>31?-(fullscale-1):(fullscale+1);
+       var destwfullscale = fullscale*(dx2-dx1+1)/dy;
+
+       while(tempY<0?-tempY:tempY<=absdy){
+               CANVAS.drawImage(img, 0, sourceY*tempY/destW2, sourceD, 1, x1+destX*tempY, tempY+y1, destW2, absscale);
+               tempY+=fullscale;
+               destW2+=destwfullscale;
+       }       
+}
+Drawing.prototype.drawWall = function(x1,y1,y2,x2,y3,y4,img){
+       if(x2==x1) x2++;
+       if(y2==y1) y2++;
+       if(y4==y3) y4++;
+       var dx = x2-x1, dy1 = y2-y1, dy2 = y4-y3;
+       var absdx=dx<0?-dx:dx;
+
+       var sourceH = img.height-1, sourceX = (img.width-1)*dy2/dx;
+       var destY = (y3-y1)/dx;
+       var tempX = 0;
+
+       var fullscale = 1.5*(dx<0?-1:1)+dx/img.width;
+       var absscale = fullscale<0?(-fullscale-1):(fullscale+1);
+       var desthfullscale = fullscale*(dy2-dy1+1)/dx;
+
+       while(tempX<0?-tempX:tempX<=absdx){
+               CANVAS.drawImage(img, sourceX*tempX/dy1, 0, 1, sourceH, tempX+x1, y1+destY*tempX, absscale, dy1);
+               tempX+=fullscale;
+               dy1+=desthfullscale;
+       }       
+}
+Drawing.prototype.zoom = function(zoom,width,height){
+       ZOOM = zoom;
+       CANVAS.translate(width>>1, height>>1);
+       CANVAS.scale(ZOOM, ZOOM);
+       CANVAS.translate(-width>>1, -height>>1);
+}
+Drawing.prototype.unZoom = function(width,height){
+       CANVAS.translate(width>>1, height>>1);
+       CANVAS.scale(1/ZOOM, 1/ZOOM);
+       CANVAS.translate(-width>>1, -height>>1);
+       ZOOM = 1;
+}
+Drawing.prototype.clear = function(x1, y1, x2, y2){ CANVAS.clearRect(x1, y1, x2-x1, y2-y1); }
+
+Draw = new Drawing();var jWorkflow=function(){return{order:function(h,j){var i=[],f,d=null,g=function(){var a=false;return{take:function(){a=true},pass:function(b){var c;a=false;if(f.length){c=f.shift();b=c.func.apply(c.context,[b,g]);a||g.pass(b)}else d.func&&d.func.apply(d.context,[])}}}(),e={andThen:function(a,b){if(typeof a!=="function")throw"expected function but was "+typeof a;i.push({func:a,context:b});return e},chill:function(a){return e.andThen(function(b,c){c.take();setTimeout(function(){c.pass(b)},a)})},start:function(a,
+b){d={func:a,context:b};f=i.slice();g.pass()}};return h?e.andThen(h,j):e}}}();if(typeof module==="object"&&typeof require==="function")module.exports=jWorkflow;
+/*
+  OpenLayers.js -- OpenLayers Map Viewer Library
+
+  Copyright 2005-2010 OpenLayers Contributors, released under the Clear BSD
+  license. Full license text below taken from http://svn.openlayers.org/trunk/openlayers/license.txt
+
+        Copyright 2005-2011 OpenLayers Contributors. All rights reserved. See
+        authors.txt for full list.
+         
+        Redistribution and use in source and binary forms, with or without modification,
+        are permitted provided that the following conditions are met:
+         
+        1. Redistributions of source code must retain the above copyright notice, this
+        list of conditions and the following disclaimer.
+         
+        2. Redistributions in binary form must reproduce the above copyright notice,
+        this list of conditions and the following disclaimer in the documentation and/or
+        other materials provided with the distribution.
+         
+        THIS SOFTWARE IS PROVIDED BY OPENLAYERS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
+        OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+        MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+        SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+        INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+        LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+        PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+        LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+        OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+        ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+         
+        The views and conclusions contained in the software and documentation are those
+        of the authors and should not be interpreted as representing official policies,
+        either expressed or implied, of OpenLayers Contributors.
+
+  Includes compressed code under the following licenses:
+
+  (For uncompressed versions of the code used please see the
+  OpenLayers SVN repository: <http://openlayers.org/>)
+
+*/
+
+/**  
+*  
+*  Contains portions of Rico <http://openrico.org/>
+* 
+*  Copyright 2005 Sabre Airline Solutions  
+*  
+*  Licensed under the Apache License, Version 2.0 (the "License"); you
+*  may not use this file except in compliance with the License. You
+*  may obtain a copy of the License at
+*  
+*         http://www.apache.org/licenses/LICENSE-2.0  
+*  
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+*  implied. See the License for the specific language governing
+*  permissions and limitations under the License. 
+*
+**/
+
+/**
+ * Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>
+ * Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+/**
+ * Contains portions of Gears <http://code.google.com/apis/gears/>
+ *
+ * Copyright 2007, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *  3. Neither the name of Google Inc. nor the names of its contributors may be
+ *     used to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Sets up google.gears.*, which is *the only* supported way to access Gears.
+ *
+ * Circumvent this file at your own risk!
+ *
+ * In the future, Gears may automatically define google.gears.* without this
+ * file. Gears may use these objects to transparently fix bugs and compatibility
+ * issues. Applications that use the code below will continue to work seamlessly
+ * when that happens.
+ */
+var OpenLayers={singleFile:true};(function(){var singleFile=(typeof OpenLayers=="object"&&OpenLayers.singleFile);var scriptLocation;window.OpenLayers={_scriptName:(!singleFile)?"lib/OpenLayers.js":"OpenLayers.js",_getScriptLocation:function(){if(scriptLocation!=undefined){return scriptLocation;}
+scriptLocation="";var isOL=new RegExp("(^|(.*?\\/))("+OpenLayers._scriptName+")(\\?|$)");var scripts=document.getElementsByTagName('script');for(var i=0,len=scripts.length;i<len;i++){var src=scripts[i].getAttribute('src');if(src){var match=src.match(isOL);if(match){scriptLocation=match[1];break;}}}
+return scriptLocation;}};if(!singleFile){var jsfiles=new Array("OpenLayers/Util.js","OpenLayers/BaseTypes.js","OpenLayers/BaseTypes/Class.js","OpenLayers/BaseTypes/Bounds.js","OpenLayers/BaseTypes/Element.js","OpenLayers/BaseTypes/LonLat.js","OpenLayers/BaseTypes/Pixel.js","OpenLayers/BaseTypes/Size.js","OpenLayers/Console.js","OpenLayers/Tween.js","Rico/Corner.js","Rico/Color.js","OpenLayers/Ajax.js","OpenLayers/Events.js","OpenLayers/Request.js","OpenLayers/Request/XMLHttpRequest.js","OpenLayers/Projection.js","OpenLayers/Map.js","OpenLayers/Layer.js","OpenLayers/Icon.js","OpenLayers/Marker.js","OpenLayers/Marker/Box.js","OpenLayers/Popup.js","OpenLayers/Tile.js","OpenLayers/Tile/Image.js","OpenLayers/Tile/Image/IFrame.js","OpenLayers/Tile/WFS.js","OpenLayers/Layer/Image.js","OpenLayers/Layer/SphericalMercator.js","OpenLayers/Layer/EventPane.js","OpenLayers/Layer/FixedZoomLevels.js","OpenLayers/Layer/Google.js","OpenLayers/Layer/Google/v3.js","OpenLayers/Layer/VirtualEarth.js","OpenLayers/Layer/Yahoo.js","OpenLayers/Layer/HTTPRequest.js","OpenLayers/Layer/Grid.js","OpenLayers/Layer/MapGuide.js","OpenLayers/Layer/MapServer.js","OpenLayers/Layer/MapServer/Untiled.js","OpenLayers/Layer/KaMap.js","OpenLayers/Layer/KaMapCache.js","OpenLayers/Layer/MultiMap.js","OpenLayers/Layer/Markers.js","OpenLayers/Layer/Text.js","OpenLayers/Layer/WorldWind.js","OpenLayers/Layer/ArcGIS93Rest.js","OpenLayers/Layer/WMS.js","OpenLayers/Layer/WMS/Untiled.js","OpenLayers/Layer/WMS/Post.js","OpenLayers/Layer/WMTS.js","OpenLayers/Layer/ArcIMS.js","OpenLayers/Layer/GeoRSS.js","OpenLayers/Layer/Boxes.js","OpenLayers/Layer/XYZ.js","OpenLayers/Layer/TMS.js","OpenLayers/Layer/TileCache.js","OpenLayers/Layer/Zoomify.js","OpenLayers/Popup/Anchored.js","OpenLayers/Popup/AnchoredBubble.js","OpenLayers/Popup/Framed.js","OpenLayers/Popup/FramedCloud.js","OpenLayers/Feature.js","OpenLayers/Feature/Vector.js","OpenLayers/Feature/WFS.js","OpenLayers/Handler.js","OpenLayers/Handler/Click.js","OpenLayers/Handler/Hover.js","OpenLayers/Handler/Point.js","OpenLayers/Handler/Path.js","OpenLayers/Handler/Polygon.js","OpenLayers/Handler/Feature.js","OpenLayers/Handler/Drag.js","OpenLayers/Handler/RegularPolygon.js","OpenLayers/Handler/Box.js","OpenLayers/Handler/MouseWheel.js","OpenLayers/Handler/Keyboard.js","OpenLayers/Control.js","OpenLayers/Control/Attribution.js","OpenLayers/Control/Button.js","OpenLayers/Control/ZoomBox.js","OpenLayers/Control/ZoomToMaxExtent.js","OpenLayers/Control/DragPan.js","OpenLayers/Control/Navigation.js","OpenLayers/Control/MouseDefaults.js","OpenLayers/Control/MousePosition.js","OpenLayers/Control/OverviewMap.js","OpenLayers/Control/KeyboardDefaults.js","OpenLayers/Control/PanZoom.js","OpenLayers/Control/PanZoomBar.js","OpenLayers/Control/ArgParser.js","OpenLayers/Control/Permalink.js","OpenLayers/Control/Scale.js","OpenLayers/Control/ScaleLine.js","OpenLayers/Control/Snapping.js","OpenLayers/Control/Split.js","OpenLayers/Control/LayerSwitcher.js","OpenLayers/Control/DrawFeature.js","OpenLayers/Control/DragFeature.js","OpenLayers/Control/ModifyFeature.js","OpenLayers/Control/Panel.js","OpenLayers/Control/SelectFeature.js","OpenLayers/Control/NavigationHistory.js","OpenLayers/Control/Measure.js","OpenLayers/Control/WMSGetFeatureInfo.js","OpenLayers/Control/WMTSGetFeatureInfo.js","OpenLayers/Control/Graticule.js","OpenLayers/Control/TransformFeature.js","OpenLayers/Control/SLDSelect.js","OpenLayers/Geometry.js","OpenLayers/Geometry/Rectangle.js","OpenLayers/Geometry/Collection.js","OpenLayers/Geometry/Point.js","OpenLayers/Geometry/MultiPoint.js","OpenLayers/Geometry/Curve.js","OpenLayers/Geometry/LineString.js","OpenLayers/Geometry/LinearRing.js","OpenLayers/Geometry/Polygon.js","OpenLayers/Geometry/MultiLineString.js","OpenLayers/Geometry/MultiPolygon.js","OpenLayers/Geometry/Surface.js","OpenLayers/Renderer.js","OpenLayers/Renderer/Elements.js","OpenLayers/Renderer/SVG.js","OpenLayers/Renderer/Canvas.js","OpenLayers/Renderer/VML.js","OpenLayers/Layer/Vector.js","OpenLayers/Layer/Vector/RootContainer.js","OpenLayers/Strategy.js","OpenLayers/Strategy/Filter.js","OpenLayers/Strategy/Fixed.js","OpenLayers/Strategy/Cluster.js","OpenLayers/Strategy/Paging.js","OpenLayers/Strategy/BBOX.js","OpenLayers/Strategy/Save.js","OpenLayers/Strategy/Refresh.js","OpenLayers/Filter.js","OpenLayers/Filter/FeatureId.js","OpenLayers/Filter/Logical.js","OpenLayers/Filter/Comparison.js","OpenLayers/Filter/Spatial.js","OpenLayers/Protocol.js","OpenLayers/Protocol/HTTP.js","OpenLayers/Protocol/SQL.js","OpenLayers/Protocol/SQL/Gears.js","OpenLayers/Protocol/WFS.js","OpenLayers/Protocol/WFS/v1.js","OpenLayers/Protocol/WFS/v1_0_0.js","OpenLayers/Protocol/WFS/v1_1_0.js","OpenLayers/Protocol/SOS.js","OpenLayers/Protocol/SOS/v1_0_0.js","OpenLayers/Layer/PointTrack.js","OpenLayers/Layer/GML.js","OpenLayers/Style.js","OpenLayers/Style2.js","OpenLayers/StyleMap.js","OpenLayers/Rule.js","OpenLayers/Format.js","OpenLayers/Format/XML.js","OpenLayers/Format/Context.js","OpenLayers/Format/ArcXML.js","OpenLayers/Format/ArcXML/Features.js","OpenLayers/Format/GML.js","OpenLayers/Format/GML/Base.js","OpenLayers/Format/GML/v2.js","OpenLayers/Format/GML/v3.js","OpenLayers/Format/Atom.js","OpenLayers/Format/KML.js","OpenLayers/Format/GeoRSS.js","OpenLayers/Format/WFS.js","OpenLayers/Format/WFSCapabilities.js","OpenLayers/Format/WFSCapabilities/v1.js","OpenLayers/Format/WFSCapabilities/v1_0_0.js","OpenLayers/Format/WFSCapabilities/v1_1_0.js","OpenLayers/Format/WFSDescribeFeatureType.js","OpenLayers/Format/WMSDescribeLayer.js","OpenLayers/Format/WMSDescribeLayer/v1_1.js","OpenLayers/Format/WKT.js","OpenLayers/Format/OSM.js","OpenLayers/Format/GPX.js","OpenLayers/Format/Filter.js","OpenLayers/Format/Filter/v1.js","OpenLayers/Format/Filter/v1_0_0.js","OpenLayers/Format/Filter/v1_1_0.js","OpenLayers/Format/SLD.js","OpenLayers/Format/SLD/v1.js","OpenLayers/Format/SLD/v1_0_0.js","OpenLayers/Format/OWSCommon/v1.js","OpenLayers/Format/OWSCommon/v1_0_0.js","OpenLayers/Format/OWSCommon/v1_1_0.js","OpenLayers/Format/CSWGetDomain.js","OpenLayers/Format/CSWGetDomain/v2_0_2.js","OpenLayers/Format/CSWGetRecords.js","OpenLayers/Format/CSWGetRecords/v2_0_2.js","OpenLayers/Format/WFST.js","OpenLayers/Format/WFST/v1.js","OpenLayers/Format/WFST/v1_0_0.js","OpenLayers/Format/WFST/v1_1_0.js","OpenLayers/Format/Text.js","OpenLayers/Format/JSON.js","OpenLayers/Format/GeoJSON.js","OpenLayers/Format/WMC.js","OpenLayers/Format/WMC/v1.js","OpenLayers/Format/WMC/v1_0_0.js","OpenLayers/Format/WMC/v1_1_0.js","OpenLayers/Format/WMSCapabilities.js","OpenLayers/Format/WMSCapabilities/v1.js","OpenLayers/Format/WMSCapabilities/v1_1.js","OpenLayers/Format/WMSCapabilities/v1_1_0.js","OpenLayers/Format/WMSCapabilities/v1_1_1.js","OpenLayers/Format/WMSCapabilities/v1_3.js","OpenLayers/Format/WMSCapabilities/v1_3_0.js","OpenLayers/Format/WMSGetFeatureInfo.js","OpenLayers/Format/SOSCapabilities.js","OpenLayers/Format/SOSCapabilities/v1_0_0.js","OpenLayers/Format/SOSGetObservation.js","OpenLayers/Format/SOSGetFeatureOfInterest.js","OpenLayers/Format/OWSContext.js","OpenLayers/Format/OWSContext/v0_3_1.js","OpenLayers/Format/WMTSCapabilities.js","OpenLayers/Format/WMTSCapabilities/v1_0_0.js","OpenLayers/Layer/WFS.js","OpenLayers/Control/GetFeature.js","OpenLayers/Control/MouseToolbar.js","OpenLayers/Control/NavToolbar.js","OpenLayers/Control/PanPanel.js","OpenLayers/Control/Pan.js","OpenLayers/Control/ZoomIn.js","OpenLayers/Control/ZoomOut.js","OpenLayers/Control/ZoomPanel.js","OpenLayers/Control/EditingToolbar.js","OpenLayers/Symbolizer.js","OpenLayers/Symbolizer/Point.js","OpenLayers/Symbolizer/Line.js","OpenLayers/Symbolizer/Polygon.js","OpenLayers/Symbolizer/Text.js","OpenLayers/Symbolizer/Raster.js","OpenLayers/Lang.js","OpenLayers/Lang/en.js");var agent=navigator.userAgent;var docWrite=(agent.match("MSIE")||agent.match("Safari"));if(docWrite){var allScriptTags=new Array(jsfiles.length);}
+var host=OpenLayers._getScriptLocation()+"lib/";for(var i=0,len=jsfiles.length;i<len;i++){if(docWrite){allScriptTags[i]="<script src='"+host+jsfiles[i]+"'></script>";}else{var s=document.createElement("script");s.src=host+jsfiles[i];var h=document.getElementsByTagName("head").length?document.getElementsByTagName("head")[0]:document.body;h.appendChild(s);}}
+if(docWrite){document.write(allScriptTags.join(""));}}})();OpenLayers.VERSION_NUMBER="OpenLayers 2.10 -- $Revision: 10721 $";OpenLayers.String={startsWith:function(str,sub){return(str.indexOf(sub)==0);},contains:function(str,sub){return(str.indexOf(sub)!=-1);},trim:function(str){return str.replace(/^\s\s*/,'').replace(/\s\s*$/,'');},camelize:function(str){var oStringList=str.split('-');var camelizedString=oStringList[0];for(var i=1,len=oStringList.length;i<len;i++){var s=oStringList[i];camelizedString+=s.charAt(0).toUpperCase()+s.substring(1);}
+return camelizedString;},format:function(template,context,args){if(!context){context=window;}
+var replacer=function(str,match){var replacement;var subs=match.split(/\.+/);for(var i=0;i<subs.length;i++){if(i==0){replacement=context;}
+replacement=replacement[subs[i]];}
+if(typeof replacement=="function"){replacement=args?replacement.apply(null,args):replacement();}
+if(typeof replacement=='undefined'){return'undefined';}else{return replacement;}};return template.replace(OpenLayers.String.tokenRegEx,replacer);},tokenRegEx:/\$\{([\w.]+?)\}/g,numberRegEx:/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/,isNumeric:function(value){return OpenLayers.String.numberRegEx.test(value);},numericIf:function(value){return OpenLayers.String.isNumeric(value)?parseFloat(value):value;}};if(!String.prototype.startsWith){String.prototype.startsWith=function(sStart){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.startsWith'}));return OpenLayers.String.startsWith(this,sStart);};}
+if(!String.prototype.contains){String.prototype.contains=function(str){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.contains'}));return OpenLayers.String.contains(this,str);};}
+if(!String.prototype.trim){String.prototype.trim=function(){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.trim'}));return OpenLayers.String.trim(this);};}
+if(!String.prototype.camelize){String.prototype.camelize=function(){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.camelize'}));return OpenLayers.String.camelize(this);};}
+OpenLayers.Number={decimalSeparator:".",thousandsSeparator:",",limitSigDigs:function(num,sig){var fig=0;if(sig>0){fig=parseFloat(num.toPrecision(sig));}
+return fig;},format:function(num,dec,tsep,dsep){dec=(typeof dec!="undefined")?dec:0;tsep=(typeof tsep!="undefined")?tsep:OpenLayers.Number.thousandsSeparator;dsep=(typeof dsep!="undefined")?dsep:OpenLayers.Number.decimalSeparator;if(dec!=null){num=parseFloat(num.toFixed(dec));}
+var parts=num.toString().split(".");if(parts.length==1&&dec==null){dec=0;}
+var integer=parts[0];if(tsep){var thousands=/(-?[0-9]+)([0-9]{3})/;while(thousands.test(integer)){integer=integer.replace(thousands,"$1"+tsep+"$2");}}
+var str;if(dec==0){str=integer;}else{var rem=parts.length>1?parts[1]:"0";if(dec!=null){rem=rem+new Array(dec-rem.length+1).join("0");}
+str=integer+dsep+rem;}
+return str;}};if(!Number.prototype.limitSigDigs){Number.prototype.limitSigDigs=function(sig){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Number.limitSigDigs'}));return OpenLayers.Number.limitSigDigs(this,sig);};}
+OpenLayers.Function={bind:function(func,object){var args=Array.prototype.slice.apply(arguments,[2]);return function(){var newArgs=args.concat(Array.prototype.slice.apply(arguments,[0]));return func.apply(object,newArgs);};},bindAsEventListener:function(func,object){return function(event){return func.call(object,event||window.event);};},False:function(){return false;},True:function(){return true;}};if(!Function.prototype.bind){Function.prototype.bind=function(){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Function.bind'}));Array.prototype.unshift.apply(arguments,[this]);return OpenLayers.Function.bind.apply(null,arguments);};}
+if(!Function.prototype.bindAsEventListener){Function.prototype.bindAsEventListener=function(object){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Function.bindAsEventListener'}));return OpenLayers.Function.bindAsEventListener(this,object);};}
+OpenLayers.Array={filter:function(array,callback,caller){var selected=[];if(Array.prototype.filter){selected=array.filter(callback,caller);}else{var len=array.length;if(typeof callback!="function"){throw new TypeError();}
+for(var i=0;i<len;i++){if(i in array){var val=array[i];if(callback.call(caller,val,i,array)){selected.push(val);}}}}
+return selected;}};OpenLayers.Date={toISOString:(function(){if("toISOString"in Date.prototype){return function(date){return date.toISOString();}}else{function pad(num,len){var str=num+"";while(str.length<len){str="0"+str;}
+return str;}
+return function(date){var str;if(isNaN(date.getTime())){str="Invalid Date";}else{str=date.getUTCFullYear()+"-"+
+pad(date.getUTCMonth()+1,2)+"-"+
+pad(date.getUTCDate(),2)+"T"+
+pad(date.getUTCHours(),2)+":"+
+pad(date.getUTCMinutes(),2)+":"+
+pad(date.getUTCSeconds(),2)+"."+
+pad(date.getUTCMilliseconds(),3)+"Z";}
+return str;}}})(),parse:function(str){var date;var elapsed=Date.parse(str);if(!isNaN(elapsed)){date=new Date(elapsed);}else{var match=str.match(/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{1,2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z|(?:[+-]\d{1,2}(?::(\d{2}))?)))?$/);var date;if(match&&(match[1]||match[7])){var year=parseInt(match[1],10)||0;var month=(parseInt(match[2],10)-1)||0;var day=parseInt(match[3],10)||1;date=new Date(Date.UTC(year,month,day));var type=match[7];if(type){var hours=parseInt(match[4],10);var minutes=parseInt(match[5],10);var secFrac=parseFloat(match[6]);var seconds=secFrac|0;var milliseconds=Math.round(1000*(secFrac-seconds));date.setUTCHours(hours,minutes,seconds,milliseconds);if(type!=="Z"){var hoursOffset=parseInt(type,10);var minutesOffset=parseInt(match[8])||0;var offset=-1000*(60*(hoursOffset*60)+minutesOffset*60);date=new Date(date.getTime()+offset);}}}else{date=new Date("invalid");}}
+return date;}};OpenLayers.Class=function(){var Class=function(){if(arguments&&arguments[0]!=OpenLayers.Class.isPrototype){this.initialize.apply(this,arguments);}};var extended={};var parent,initialize,Type;for(var i=0,len=arguments.length;i<len;++i){Type=arguments[i];if(typeof Type=="function"){if(i==0&&len>1){initialize=Type.prototype.initialize;Type.prototype.initialize=function(){};extended=new Type();if(initialize===undefined){delete Type.prototype.initialize;}else{Type.prototype.initialize=initialize;}}
+parent=Type.prototype;}else{parent=Type;}
+OpenLayers.Util.extend(extended,parent);}
+Class.prototype=extended;return Class;};OpenLayers.Class.isPrototype=function(){};OpenLayers.Class.create=function(){return function(){if(arguments&&arguments[0]!=OpenLayers.Class.isPrototype){this.initialize.apply(this,arguments);}};};OpenLayers.Class.inherit=function(){var superClass=arguments[0];var proto=new superClass(OpenLayers.Class.isPrototype);for(var i=1,len=arguments.length;i<len;i++){if(typeof arguments[i]=="function"){var mixin=arguments[i];arguments[i]=new mixin(OpenLayers.Class.isPrototype);}
+OpenLayers.Util.extend(proto,arguments[i]);}
+return proto;};OpenLayers.Util={};OpenLayers.Util.getElement=function(){var elements=[];for(var i=0,len=arguments.length;i<len;i++){var element=arguments[i];if(typeof element=='string'){element=document.getElementById(element);}
+if(arguments.length==1){return element;}
+elements.push(element);}
+return elements;};OpenLayers.Util.isElement=function(o){return!!(o&&o.nodeType===1);};if(typeof window.$==="undefined"){window.$=OpenLayers.Util.getElement;}
+OpenLayers.Util.extend=function(destination,source){destination=destination||{};if(source){for(var property in source){var value=source[property];if(value!==undefined){destination[property]=value;}}
+var sourceIsEvt=typeof window.Event=="function"&&source instanceof window.Event;if(!sourceIsEvt&&source.hasOwnProperty&&source.hasOwnProperty('toString')){destination.toString=source.toString;}}
+return destination;};OpenLayers.Util.removeItem=function(array,item){for(var i=array.length-1;i>=0;i--){if(array[i]==item){array.splice(i,1);}}
+return array;};OpenLayers.Util.clearArray=function(array){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'array = []'}));array.length=0;};OpenLayers.Util.indexOf=function(array,obj){if(typeof array.indexOf=="function"){return array.indexOf(obj);}else{for(var i=0,len=array.length;i<len;i++){if(array[i]==obj){return i;}}
+return-1;}};OpenLayers.Util.modifyDOMElement=function(element,id,px,sz,position,border,overflow,opacity){if(id){element.id=id;}
+if(px){element.style.left=px.x+"px";element.style.top=px.y+"px";}
+if(sz){element.style.width=sz.w+"px";element.style.height=sz.h+"px";}
+if(position){element.style.position=position;}
+if(border){element.style.border=border;}
+if(overflow){element.style.overflow=overflow;}
+if(parseFloat(opacity)>=0.0&&parseFloat(opacity)<1.0){element.style.filter='alpha(opacity='+(opacity*100)+')';element.style.opacity=opacity;}else if(parseFloat(opacity)==1.0){element.style.filter='';element.style.opacity='';}};OpenLayers.Util.createDiv=function(id,px,sz,imgURL,position,border,overflow,opacity){var dom=document.createElement('div');if(imgURL){dom.style.backgroundImage='url('+imgURL+')';}
+if(!id){id=OpenLayers.Util.createUniqueID("OpenLayersDiv");}
+if(!position){position="absolute";}
+OpenLayers.Util.modifyDOMElement(dom,id,px,sz,position,border,overflow,opacity);return dom;};OpenLayers.Util.createImage=function(id,px,sz,imgURL,position,border,opacity,delayDisplay){var image=document.createElement("img");if(!id){id=OpenLayers.Util.createUniqueID("OpenLayersDiv");}
+if(!position){position="relative";}
+OpenLayers.Util.modifyDOMElement(image,id,px,sz,position,border,null,opacity);if(delayDisplay){image.style.display="none";OpenLayers.Event.observe(image,"load",OpenLayers.Function.bind(OpenLayers.Util.onImageLoad,image));OpenLayers.Event.observe(image,"error",OpenLayers.Function.bind(OpenLayers.Util.onImageLoadError,image));}
+image.style.alt=id;image.galleryImg="no";if(imgURL){image.src=imgURL;}
+return image;};OpenLayers.Util.setOpacity=function(element,opacity){OpenLayers.Util.modifyDOMElement(element,null,null,null,null,null,null,opacity);};OpenLayers.Util.onImageLoad=function(){if(!this.viewRequestID||(this.map&&this.viewRequestID==this.map.viewRequestID)){this.style.display="";}
+OpenLayers.Element.removeClass(this,"olImageLoadError");};OpenLayers.IMAGE_RELOAD_ATTEMPTS=0;OpenLayers.Util.onImageLoadError=function(){this._attempts=(this._attempts)?(this._attempts+1):1;if(this._attempts<=OpenLayers.IMAGE_RELOAD_ATTEMPTS){var urls=this.urls;if(urls&&urls instanceof Array&&urls.length>1){var src=this.src.toString();var current_url,k;for(k=0;current_url=urls[k];k++){if(src.indexOf(current_url)!=-1){break;}}
+var guess=Math.floor(urls.length*Math.random());var new_url=urls[guess];k=0;while(new_url==current_url&&k++<4){guess=Math.floor(urls.length*Math.random());new_url=urls[guess];}
+this.src=src.replace(current_url,new_url);}else{this.src=this.src;}}else{OpenLayers.Element.addClass(this,"olImageLoadError");}
+this.style.display="";};OpenLayers.Util.alphaHackNeeded=null;OpenLayers.Util.alphaHack=function(){if(OpenLayers.Util.alphaHackNeeded==null){var arVersion=navigator.appVersion.split("MSIE");var version=parseFloat(arVersion[1]);var filter=false;try{filter=!!(document.body.filters);}catch(e){}
+OpenLayers.Util.alphaHackNeeded=(filter&&(version>=5.5)&&(version<7));}
+return OpenLayers.Util.alphaHackNeeded;};OpenLayers.Util.modifyAlphaImageDiv=function(div,id,px,sz,imgURL,position,border,sizing,opacity){OpenLayers.Util.modifyDOMElement(div,id,px,sz,position,null,null,opacity);var img=div.childNodes[0];if(imgURL){img.src=imgURL;}
+OpenLayers.Util.modifyDOMElement(img,div.id+"_innerImage",null,sz,"relative",border);if(OpenLayers.Util.alphaHack()){if(div.style.display!="none"){div.style.display="inline-block";}
+if(sizing==null){sizing="scale";}
+div.style.filter="progid:DXImageTransform.Microsoft"+".AlphaImageLoader(src='"+img.src+"', "+"sizingMethod='"+sizing+"')";if(parseFloat(div.style.opacity)>=0.0&&parseFloat(div.style.opacity)<1.0){div.style.filter+=" alpha(opacity="+div.style.opacity*100+")";}
+img.style.filter="alpha(opacity=0)";}};OpenLayers.Util.createAlphaImageDiv=function(id,px,sz,imgURL,position,border,sizing,opacity,delayDisplay){var div=OpenLayers.Util.createDiv();var img=OpenLayers.Util.createImage(null,null,null,null,null,null,null,false);div.appendChild(img);if(delayDisplay){img.style.display="none";OpenLayers.Event.observe(img,"load",OpenLayers.Function.bind(OpenLayers.Util.onImageLoad,div));OpenLayers.Event.observe(img,"error",OpenLayers.Function.bind(OpenLayers.Util.onImageLoadError,div));}
+OpenLayers.Util.modifyAlphaImageDiv(div,id,px,sz,imgURL,position,border,sizing,opacity);return div;};OpenLayers.Util.upperCaseObject=function(object){var uObject={};for(var key in object){uObject[key.toUpperCase()]=object[key];}
+return uObject;};OpenLayers.Util.applyDefaults=function(to,from){to=to||{};var fromIsEvt=typeof window.Event=="function"&&from instanceof window.Event;for(var key in from){if(to[key]===undefined||(!fromIsEvt&&from.hasOwnProperty&&from.hasOwnProperty(key)&&!to.hasOwnProperty(key))){to[key]=from[key];}}
+if(!fromIsEvt&&from&&from.hasOwnProperty&&from.hasOwnProperty('toString')&&!to.hasOwnProperty('toString')){to.toString=from.toString;}
+return to;};OpenLayers.Util.getParameterString=function(params){var paramsArray=[];for(var key in params){var value=params[key];if((value!=null)&&(typeof value!='function')){var encodedValue;if(typeof value=='object'&&value.constructor==Array){var encodedItemArray=[];var item;for(var itemIndex=0,len=value.length;itemIndex<len;itemIndex++){item=value[itemIndex];encodedItemArray.push(encodeURIComponent((item===null||item===undefined)?"":item));}
+encodedValue=encodedItemArray.join(",");}
+else{encodedValue=encodeURIComponent(value);}
+paramsArray.push(encodeURIComponent(key)+"="+encodedValue);}}
+return paramsArray.join("&");};OpenLayers.Util.urlAppend=function(url,paramStr){var newUrl=url;if(paramStr){var parts=(url+" ").split(/[?&]/);newUrl+=(parts.pop()===" "?paramStr:parts.length?"&"+paramStr:"?"+paramStr);}
+return newUrl;};OpenLayers.ImgPath='';OpenLayers.Util.getImagesLocation=function(){return OpenLayers.ImgPath||(OpenLayers._getScriptLocation()+"img/");};OpenLayers.Util.Try=function(){var returnValue=null;for(var i=0,len=arguments.length;i<len;i++){var lambda=arguments[i];try{returnValue=lambda();break;}catch(e){}}
+return returnValue;};OpenLayers.Util.getNodes=function(p,tagName){var nodes=OpenLayers.Util.Try(function(){return OpenLayers.Util._getNodes(p.documentElement.childNodes,tagName);},function(){return OpenLayers.Util._getNodes(p.childNodes,tagName);});return nodes;};OpenLayers.Util._getNodes=function(nodes,tagName){var retArray=[];for(var i=0,len=nodes.length;i<len;i++){if(nodes[i].nodeName==tagName){retArray.push(nodes[i]);}}
+return retArray;};OpenLayers.Util.getTagText=function(parent,item,index){var result=OpenLayers.Util.getNodes(parent,item);if(result&&(result.length>0))
+{if(!index){index=0;}
+if(result[index].childNodes.length>1){return result.childNodes[1].nodeValue;}
+else if(result[index].childNodes.length==1){return result[index].firstChild.nodeValue;}}else{return"";}};OpenLayers.Util.getXmlNodeValue=function(node){var val=null;OpenLayers.Util.Try(function(){val=node.text;if(!val){val=node.textContent;}
+if(!val){val=node.firstChild.nodeValue;}},function(){val=node.textContent;});return val;};OpenLayers.Util.mouseLeft=function(evt,div){var target=(evt.relatedTarget)?evt.relatedTarget:evt.toElement;while(target!=div&&target!=null){target=target.parentNode;}
+return(target!=div);};OpenLayers.Util.DEFAULT_PRECISION=14;OpenLayers.Util.toFloat=function(number,precision){if(precision==null){precision=OpenLayers.Util.DEFAULT_PRECISION;}
+var number;if(precision==0){number=parseFloat(number);}else{number=parseFloat(parseFloat(number).toPrecision(precision));}
+return number;};OpenLayers.Util.rad=function(x){return x*Math.PI/180;};OpenLayers.Util.deg=function(x){return x*180/Math.PI;};OpenLayers.Util.VincentyConstants={a:6378137,b:6356752.3142,f:1/298.257223563};OpenLayers.Util.distVincenty=function(p1,p2){var ct=OpenLayers.Util.VincentyConstants;var a=ct.a,b=ct.b,f=ct.f;var L=OpenLayers.Util.rad(p2.lon-p1.lon);var U1=Math.atan((1-f)*Math.tan(OpenLayers.Util.rad(p1.lat)));var U2=Math.atan((1-f)*Math.tan(OpenLayers.Util.rad(p2.lat)));var sinU1=Math.sin(U1),cosU1=Math.cos(U1);var sinU2=Math.sin(U2),cosU2=Math.cos(U2);var lambda=L,lambdaP=2*Math.PI;var iterLimit=20;while(Math.abs(lambda-lambdaP)>1e-12&&--iterLimit>0){var sinLambda=Math.sin(lambda),cosLambda=Math.cos(lambda);var sinSigma=Math.sqrt((cosU2*sinLambda)*(cosU2*sinLambda)+
+(cosU1*sinU2-sinU1*cosU2*cosLambda)*(cosU1*sinU2-sinU1*cosU2*cosLambda));if(sinSigma==0){return 0;}
+var cosSigma=sinU1*sinU2+cosU1*cosU2*cosLambda;var sigma=Math.atan2(sinSigma,cosSigma);var alpha=Math.asin(cosU1*cosU2*sinLambda/sinSigma);var cosSqAlpha=Math.cos(alpha)*Math.cos(alpha);var cos2SigmaM=cosSigma-2*sinU1*sinU2/cosSqAlpha;var C=f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));lambdaP=lambda;lambda=L+(1-C)*f*Math.sin(alpha)*(sigma+C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));}
+if(iterLimit==0){return NaN;}
+var uSq=cosSqAlpha*(a*a-b*b)/(b*b);var A=1+uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));var B=uSq/1024*(256+uSq*(-128+uSq*(74-47*uSq)));var deltaSigma=B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
+B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));var s=b*A*(sigma-deltaSigma);var d=s.toFixed(3)/1000;return d;};OpenLayers.Util.destinationVincenty=function(lonlat,brng,dist){var u=OpenLayers.Util;var ct=u.VincentyConstants;var a=ct.a,b=ct.b,f=ct.f;var lon1=lonlat.lon;var lat1=lonlat.lat;var s=dist;var alpha1=u.rad(brng);var sinAlpha1=Math.sin(alpha1);var cosAlpha1=Math.cos(alpha1);var tanU1=(1-f)*Math.tan(u.rad(lat1));var cosU1=1/Math.sqrt((1+tanU1*tanU1)),sinU1=tanU1*cosU1;var sigma1=Math.atan2(tanU1,cosAlpha1);var sinAlpha=cosU1*sinAlpha1;var cosSqAlpha=1-sinAlpha*sinAlpha;var uSq=cosSqAlpha*(a*a-b*b)/(b*b);var A=1+uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));var B=uSq/1024*(256+uSq*(-128+uSq*(74-47*uSq)));var sigma=s/(b*A),sigmaP=2*Math.PI;while(Math.abs(sigma-sigmaP)>1e-12){var cos2SigmaM=Math.cos(2*sigma1+sigma);var sinSigma=Math.sin(sigma);var cosSigma=Math.cos(sigma);var deltaSigma=B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
+B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));sigmaP=sigma;sigma=s/(b*A)+deltaSigma;}
+var tmp=sinU1*sinSigma-cosU1*cosSigma*cosAlpha1;var lat2=Math.atan2(sinU1*cosSigma+cosU1*sinSigma*cosAlpha1,(1-f)*Math.sqrt(sinAlpha*sinAlpha+tmp*tmp));var lambda=Math.atan2(sinSigma*sinAlpha1,cosU1*cosSigma-sinU1*sinSigma*cosAlpha1);var C=f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));var L=lambda-(1-C)*f*sinAlpha*(sigma+C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));var revAz=Math.atan2(sinAlpha,-tmp);return new OpenLayers.LonLat(lon1+u.deg(L),u.deg(lat2));};OpenLayers.Util.getParameters=function(url){url=url||window.location.href;var paramsString="";if(OpenLayers.String.contains(url,'?')){var start=url.indexOf('?')+1;var end=OpenLayers.String.contains(url,"#")?url.indexOf('#'):url.length;paramsString=url.substring(start,end);}
+var parameters={};var pairs=paramsString.split(/[&;]/);for(var i=0,len=pairs.length;i<len;++i){var keyValue=pairs[i].split('=');if(keyValue[0]){var key=decodeURIComponent(keyValue[0]);var value=keyValue[1]||'';value=decodeURIComponent(value.replace(/\+/g," ")).split(",");if(value.length==1){value=value[0];}
+parameters[key]=value;}}
+return parameters;};OpenLayers.Util.getArgs=function(url){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Util.getParameters'}));return OpenLayers.Util.getParameters(url);};OpenLayers.Util.lastSeqID=0;OpenLayers.Util.createUniqueID=function(prefix){if(prefix==null){prefix="id_";}
+OpenLayers.Util.lastSeqID+=1;return prefix+OpenLayers.Util.lastSeqID;};OpenLayers.INCHES_PER_UNIT={'inches':1.0,'ft':12.0,'mi':63360.0,'m':39.3701,'km':39370.1,'dd':4374754,'yd':36};OpenLayers.INCHES_PER_UNIT["in"]=OpenLayers.INCHES_PER_UNIT.inches;OpenLayers.INCHES_PER_UNIT["degrees"]=OpenLayers.INCHES_PER_UNIT.dd;OpenLayers.INCHES_PER_UNIT["nmi"]=1852*OpenLayers.INCHES_PER_UNIT.m;OpenLayers.METERS_PER_INCH=0.02540005080010160020;OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT,{"Inch":OpenLayers.INCHES_PER_UNIT.inches,"Meter":1.0/OpenLayers.METERS_PER_INCH,"Foot":0.30480060960121920243/OpenLayers.METERS_PER_INCH,"IFoot":0.30480000000000000000/OpenLayers.METERS_PER_INCH,"ClarkeFoot":0.3047972651151/OpenLayers.METERS_PER_INCH,"SearsFoot":0.30479947153867624624/OpenLayers.METERS_PER_INCH,"GoldCoastFoot":0.30479971018150881758/OpenLayers.METERS_PER_INCH,"IInch":0.02540000000000000000/OpenLayers.METERS_PER_INCH,"MicroInch":0.00002540000000000000/OpenLayers.METERS_PER_INCH,"Mil":0.00000002540000000000/OpenLayers.METERS_PER_INCH,"Centimeter":0.01000000000000000000/OpenLayers.METERS_PER_INCH,"Kilometer":1000.00000000000000000000/OpenLayers.METERS_PER_INCH,"Yard":0.91440182880365760731/OpenLayers.METERS_PER_INCH,"SearsYard":0.914398414616029/OpenLayers.METERS_PER_INCH,"IndianYard":0.91439853074444079983/OpenLayers.METERS_PER_INCH,"IndianYd37":0.91439523/OpenLayers.METERS_PER_INCH,"IndianYd62":0.9143988/OpenLayers.METERS_PER_INCH,"IndianYd75":0.9143985/OpenLayers.METERS_PER_INCH,"IndianFoot":0.30479951/OpenLayers.METERS_PER_INCH,"IndianFt37":0.30479841/OpenLayers.METERS_PER_INCH,"IndianFt62":0.3047996/OpenLayers.METERS_PER_INCH,"IndianFt75":0.3047995/OpenLayers.METERS_PER_INCH,"Mile":1609.34721869443738887477/OpenLayers.METERS_PER_INCH,"IYard":0.91440000000000000000/OpenLayers.METERS_PER_INCH,"IMile":1609.34400000000000000000/OpenLayers.METERS_PER_INCH,"NautM":1852.00000000000000000000/OpenLayers.METERS_PER_INCH,"Lat-66":110943.316488932731/OpenLayers.METERS_PER_INCH,"Lat-83":110946.25736872234125/OpenLayers.METERS_PER_INCH,"Decimeter":0.10000000000000000000/OpenLayers.METERS_PER_INCH,"Millimeter":0.00100000000000000000/OpenLayers.METERS_PER_INCH,"Dekameter":10.00000000000000000000/OpenLayers.METERS_PER_INCH,"Decameter":10.00000000000000000000/OpenLayers.METERS_PER_INCH,"Hectometer":100.00000000000000000000/OpenLayers.METERS_PER_INCH,"GermanMeter":1.0000135965/OpenLayers.METERS_PER_INCH,"CaGrid":0.999738/OpenLayers.METERS_PER_INCH,"ClarkeChain":20.1166194976/OpenLayers.METERS_PER_INCH,"GunterChain":20.11684023368047/OpenLayers.METERS_PER_INCH,"BenoitChain":20.116782494375872/OpenLayers.METERS_PER_INCH,"SearsChain":20.11676512155/OpenLayers.METERS_PER_INCH,"ClarkeLink":0.201166194976/OpenLayers.METERS_PER_INCH,"GunterLink":0.2011684023368047/OpenLayers.METERS_PER_INCH,"BenoitLink":0.20116782494375872/OpenLayers.METERS_PER_INCH,"SearsLink":0.2011676512155/OpenLayers.METERS_PER_INCH,"Rod":5.02921005842012/OpenLayers.METERS_PER_INCH,"IntnlChain":20.1168/OpenLayers.METERS_PER_INCH,"IntnlLink":0.201168/OpenLayers.METERS_PER_INCH,"Perch":5.02921005842012/OpenLayers.METERS_PER_INCH,"Pole":5.02921005842012/OpenLayers.METERS_PER_INCH,"Furlong":201.1684023368046/OpenLayers.METERS_PER_INCH,"Rood":3.778266898/OpenLayers.METERS_PER_INCH,"CapeFoot":0.3047972615/OpenLayers.METERS_PER_INCH,"Brealey":375.00000000000000000000/OpenLayers.METERS_PER_INCH,"ModAmFt":0.304812252984505969011938/OpenLayers.METERS_PER_INCH,"Fathom":1.8288/OpenLayers.METERS_PER_INCH,"NautM-UK":1853.184/OpenLayers.METERS_PER_INCH,"50kilometers":50000.0/OpenLayers.METERS_PER_INCH,"150kilometers":150000.0/OpenLayers.METERS_PER_INCH});OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT,{"mm":OpenLayers.INCHES_PER_UNIT["Meter"]/1000.0,"cm":OpenLayers.INCHES_PER_UNIT["Meter"]/100.0,"dm":OpenLayers.INCHES_PER_UNIT["Meter"]*100.0,"km":OpenLayers.INCHES_PER_UNIT["Meter"]*1000.0,"kmi":OpenLayers.INCHES_PER_UNIT["nmi"],"fath":OpenLayers.INCHES_PER_UNIT["Fathom"],"ch":OpenLayers.INCHES_PER_UNIT["IntnlChain"],"link":OpenLayers.INCHES_PER_UNIT["IntnlLink"],"us-in":OpenLayers.INCHES_PER_UNIT["inches"],"us-ft":OpenLayers.INCHES_PER_UNIT["Foot"],"us-yd":OpenLayers.INCHES_PER_UNIT["Yard"],"us-ch":OpenLayers.INCHES_PER_UNIT["GunterChain"],"us-mi":OpenLayers.INCHES_PER_UNIT["Mile"],"ind-yd":OpenLayers.INCHES_PER_UNIT["IndianYd37"],"ind-ft":OpenLayers.INCHES_PER_UNIT["IndianFt37"],"ind-ch":20.11669506/OpenLayers.METERS_PER_INCH});OpenLayers.DOTS_PER_INCH=72;OpenLayers.Util.normalizeScale=function(scale){var normScale=(scale>1.0)?(1.0/scale):scale;return normScale;};OpenLayers.Util.getResolutionFromScale=function(scale,units){var resolution;if(scale){if(units==null){units="degrees";}
+var normScale=OpenLayers.Util.normalizeScale(scale);resolution=1/(normScale*OpenLayers.INCHES_PER_UNIT[units]*OpenLayers.DOTS_PER_INCH);}
+return resolution;};OpenLayers.Util.getScaleFromResolution=function(resolution,units){if(units==null){units="degrees";}
+var scale=resolution*OpenLayers.INCHES_PER_UNIT[units]*OpenLayers.DOTS_PER_INCH;return scale;};OpenLayers.Util.safeStopPropagation=function(evt){OpenLayers.Event.stop(evt,true);};OpenLayers.Util.pagePosition=function(forElement){var valueT=0,valueL=0;var element=forElement;var child=forElement;while(element){if(element==document.body){if(OpenLayers.Element.getStyle(child,'position')=='absolute'){break;}}
+valueT+=element.offsetTop||0;valueL+=element.offsetLeft||0;child=element;try{element=element.offsetParent;}catch(e){OpenLayers.Console.error(OpenLayers.i18n("pagePositionFailed",{'elemId':element.id}));break;}}
+element=forElement;while(element){valueT-=element.scrollTop||0;valueL-=element.scrollLeft||0;element=element.parentNode;}
+return[valueL,valueT];};OpenLayers.Util.isEquivalentUrl=function(url1,url2,options){options=options||{};OpenLayers.Util.applyDefaults(options,{ignoreCase:true,ignorePort80:true,ignoreHash:true});var urlObj1=OpenLayers.Util.createUrlObject(url1,options);var urlObj2=OpenLayers.Util.createUrlObject(url2,options);for(var key in urlObj1){if(key!=="args"){if(urlObj1[key]!=urlObj2[key]){return false;}}}
+for(var key in urlObj1.args){if(urlObj1.args[key]!=urlObj2.args[key]){return false;}
+delete urlObj2.args[key];}
+for(var key in urlObj2.args){return false;}
+return true;};OpenLayers.Util.createUrlObject=function(url,options){options=options||{};if(!(/^\w+:\/\//).test(url)){var loc=window.location;var port=loc.port?":"+loc.port:"";var fullUrl=loc.protocol+"//"+loc.host.split(":").shift()+port;if(url.indexOf("/")===0){url=fullUrl+url;}else{var parts=loc.pathname.split("/");parts.pop();url=fullUrl+parts.join("/")+"/"+url;}}
+if(options.ignoreCase){url=url.toLowerCase();}
+var a=document.createElement('a');a.href=url;var urlObject={};urlObject.host=a.host.split(":").shift();urlObject.protocol=a.protocol;if(options.ignorePort80){urlObject.port=(a.port=="80"||a.port=="0")?"":a.port;}else{urlObject.port=(a.port==""||a.port=="0")?"80":a.port;}
+urlObject.hash=(options.ignoreHash||a.hash==="#")?"":a.hash;var queryString=a.search;if(!queryString){var qMark=url.indexOf("?");queryString=(qMark!=-1)?url.substr(qMark):"";}
+urlObject.args=OpenLayers.Util.getParameters(queryString);urlObject.pathname=(a.pathname.charAt(0)=="/")?a.pathname:"/"+a.pathname;return urlObject;};OpenLayers.Util.removeTail=function(url){var head=null;var qMark=url.indexOf("?");var hashMark=url.indexOf("#");if(qMark==-1){head=(hashMark!=-1)?url.substr(0,hashMark):url;}else{head=(hashMark!=-1)?url.substr(0,Math.min(qMark,hashMark)):url.substr(0,qMark);}
+return head;};OpenLayers.Util.getBrowserName=function(){var browserName="";var ua=navigator.userAgent.toLowerCase();if(ua.indexOf("opera")!=-1){browserName="opera";}else if(ua.indexOf("msie")!=-1){browserName="msie";}else if(ua.indexOf("safari")!=-1){browserName="safari";}else if(ua.indexOf("mozilla")!=-1){if(ua.indexOf("firefox")!=-1){browserName="firefox";}else{browserName="mozilla";}}
+return browserName;};OpenLayers.Util.getRenderedDimensions=function(contentHTML,size,options){var w,h;var container=document.createElement("div");container.style.visibility="hidden";var containerElement=(options&&options.containerElement)?options.containerElement:document.body;if(size){if(size.w){w=size.w;container.style.width=w+"px";}else if(size.h){h=size.h;container.style.height=h+"px";}}
+if(options&&options.displayClass){container.className=options.displayClass;}
+var content=document.createElement("div");content.innerHTML=contentHTML;content.style.overflow="visible";if(content.childNodes){for(var i=0,l=content.childNodes.length;i<l;i++){if(!content.childNodes[i].style)continue;content.childNodes[i].style.overflow="visible";}}
+container.appendChild(content);containerElement.appendChild(container);var parentHasPositionAbsolute=false;var parent=container.parentNode;while(parent&&parent.tagName.toLowerCase()!="body"){var parentPosition=OpenLayers.Element.getStyle(parent,"position");if(parentPosition=="absolute"){parentHasPositionAbsolute=true;break;}else if(parentPosition&&parentPosition!="static"){break;}
+parent=parent.parentNode;}
+if(!parentHasPositionAbsolute){container.style.position="absolute";}
+if(!w){w=parseInt(content.scrollWidth);container.style.width=w+"px";}
+if(!h){h=parseInt(content.scrollHeight);}
+container.removeChild(content);containerElement.removeChild(container);return new OpenLayers.Size(w,h);};OpenLayers.Util.getScrollbarWidth=function(){var scrollbarWidth=OpenLayers.Util._scrollbarWidth;if(scrollbarWidth==null){var scr=null;var inn=null;var wNoScroll=0;var wScroll=0;scr=document.createElement('div');scr.style.position='absolute';scr.style.top='-1000px';scr.style.left='-1000px';scr.style.width='100px';scr.style.height='50px';scr.style.overflow='hidden';inn=document.createElement('div');inn.style.width='100%';inn.style.height='200px';scr.appendChild(inn);document.body.appendChild(scr);wNoScroll=inn.offsetWidth;scr.style.overflow='scroll';wScroll=inn.offsetWidth;document.body.removeChild(document.body.lastChild);OpenLayers.Util._scrollbarWidth=(wNoScroll-wScroll);scrollbarWidth=OpenLayers.Util._scrollbarWidth;}
+return scrollbarWidth;};OpenLayers.Util.getFormattedLonLat=function(coordinate,axis,dmsOption){if(!dmsOption){dmsOption='dms';}
+var abscoordinate=Math.abs(coordinate)
+var coordinatedegrees=Math.floor(abscoordinate);var coordinateminutes=(abscoordinate-coordinatedegrees)/(1/60);var tempcoordinateminutes=coordinateminutes;coordinateminutes=Math.floor(coordinateminutes);var coordinateseconds=(tempcoordinateminutes-coordinateminutes)/(1/60);coordinateseconds=Math.round(coordinateseconds*10);coordinateseconds/=10;if(coordinatedegrees<10){coordinatedegrees="0"+coordinatedegrees;}
+var str=coordinatedegrees+"\u00B0";if(dmsOption.indexOf('dm')>=0){if(coordinateminutes<10){coordinateminutes="0"+coordinateminutes;}
+str+=coordinateminutes+"'";if(dmsOption.indexOf('dms')>=0){if(coordinateseconds<10){coordinateseconds="0"+coordinateseconds;}
+str+=coordinateseconds+'"';}}
+if(axis=="lon"){str+=coordinate<0?OpenLayers.i18n("W"):OpenLayers.i18n("E");}else{str+=coordinate<0?OpenLayers.i18n("S"):OpenLayers.i18n("N");}
+return str;};OpenLayers.Rico=new Object();OpenLayers.Rico.Corner={round:function(e,options){e=OpenLayers.Util.getElement(e);this._setOptions(options);var color=this.options.color;if(this.options.color=="fromElement"){color=this._background(e);}
+var bgColor=this.options.bgColor;if(this.options.bgColor=="fromParent"){bgColor=this._background(e.offsetParent);}
+this._roundCornersImpl(e,color,bgColor);},changeColor:function(theDiv,newColor){theDiv.style.backgroundColor=newColor;var spanElements=theDiv.parentNode.getElementsByTagName("span");for(var currIdx=0;currIdx<spanElements.length;currIdx++){spanElements[currIdx].style.backgroundColor=newColor;}},changeOpacity:function(theDiv,newOpacity){var mozillaOpacity=newOpacity;var ieOpacity='alpha(opacity='+newOpacity*100+')';theDiv.style.opacity=mozillaOpacity;theDiv.style.filter=ieOpacity;var spanElements=theDiv.parentNode.getElementsByTagName("span");for(var currIdx=0;currIdx<spanElements.length;currIdx++){spanElements[currIdx].style.opacity=mozillaOpacity;spanElements[currIdx].style.filter=ieOpacity;}},reRound:function(theDiv,options){var topRico=theDiv.parentNode.childNodes[0];var bottomRico=theDiv.parentNode.childNodes[2];theDiv.parentNode.removeChild(topRico);theDiv.parentNode.removeChild(bottomRico);this.round(theDiv.parentNode,options);},_roundCornersImpl:function(e,color,bgColor){if(this.options.border){this._renderBorder(e,bgColor);}
+if(this._isTopRounded()){this._roundTopCorners(e,color,bgColor);}
+if(this._isBottomRounded()){this._roundBottomCorners(e,color,bgColor);}},_renderBorder:function(el,bgColor){var borderValue="1px solid "+this._borderColor(bgColor);var borderL="border-left: "+borderValue;var borderR="border-right: "+borderValue;var style="style='"+borderL+";"+borderR+"'";el.innerHTML="<div "+style+">"+el.innerHTML+"</div>";},_roundTopCorners:function(el,color,bgColor){var corner=this._createCorner(bgColor);for(var i=0;i<this.options.numSlices;i++){corner.appendChild(this._createCornerSlice(color,bgColor,i,"top"));}
+el.style.paddingTop=0;el.insertBefore(corner,el.firstChild);},_roundBottomCorners:function(el,color,bgColor){var corner=this._createCorner(bgColor);for(var i=(this.options.numSlices-1);i>=0;i--){corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));}
+el.style.paddingBottom=0;el.appendChild(corner);},_createCorner:function(bgColor){var corner=document.createElement("div");corner.style.backgroundColor=(this._isTransparent()?"transparent":bgColor);return corner;},_createCornerSlice:function(color,bgColor,n,position){var slice=document.createElement("span");var inStyle=slice.style;inStyle.backgroundColor=color;inStyle.display="block";inStyle.height="1px";inStyle.overflow="hidden";inStyle.fontSize="1px";var borderColor=this._borderColor(color,bgColor);if(this.options.border&&n==0){inStyle.borderTopStyle="solid";inStyle.borderTopWidth="1px";inStyle.borderLeftWidth="0px";inStyle.borderRightWidth="0px";inStyle.borderBottomWidth="0px";inStyle.height="0px";inStyle.borderColor=borderColor;}
+else if(borderColor){inStyle.borderColor=borderColor;inStyle.borderStyle="solid";inStyle.borderWidth="0px 1px";}
+if(!this.options.compact&&(n==(this.options.numSlices-1))){inStyle.height="2px";}
+this._setMargin(slice,n,position);this._setBorder(slice,n,position);return slice;},_setOptions:function(options){this.options={corners:"all",color:"fromElement",bgColor:"fromParent",blend:true,border:false,compact:false};OpenLayers.Util.extend(this.options,options||{});this.options.numSlices=this.options.compact?2:4;if(this._isTransparent()){this.options.blend=false;}},_whichSideTop:function(){if(this._hasString(this.options.corners,"all","top")){return"";}
+if(this.options.corners.indexOf("tl")>=0&&this.options.corners.indexOf("tr")>=0){return"";}
+if(this.options.corners.indexOf("tl")>=0){return"left";}else if(this.options.corners.indexOf("tr")>=0){return"right";}
+return"";},_whichSideBottom:function(){if(this._hasString(this.options.corners,"all","bottom")){return"";}
+if(this.options.corners.indexOf("bl")>=0&&this.options.corners.indexOf("br")>=0){return"";}
+if(this.options.corners.indexOf("bl")>=0){return"left";}else if(this.options.corners.indexOf("br")>=0){return"right";}
+return"";},_borderColor:function(color,bgColor){if(color=="transparent"){return bgColor;}else if(this.options.border){return this.options.border;}else if(this.options.blend){return this._blend(bgColor,color);}else{return"";}},_setMargin:function(el,n,corners){var marginSize=this._marginSize(n);var whichSide=corners=="top"?this._whichSideTop():this._whichSideBottom();if(whichSide=="left"){el.style.marginLeft=marginSize+"px";el.style.marginRight="0px";}
+else if(whichSide=="right"){el.style.marginRight=marginSize+"px";el.style.marginLeft="0px";}
+else{el.style.marginLeft=marginSize+"px";el.style.marginRight=marginSize+"px";}},_setBorder:function(el,n,corners){var borderSize=this._borderSize(n);var whichSide=corners=="top"?this._whichSideTop():this._whichSideBottom();if(whichSide=="left"){el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth="0px";}
+else if(whichSide=="right"){el.style.borderRightWidth=borderSize+"px";el.style.borderLeftWidth="0px";}
+else{el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth=borderSize+"px";}
+if(this.options.border!=false){el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth=borderSize+"px";}},_marginSize:function(n){if(this._isTransparent()){return 0;}
+var marginSizes=[5,3,2,1];var blendedMarginSizes=[3,2,1,0];var compactMarginSizes=[2,1];var smBlendedMarginSizes=[1,0];if(this.options.compact&&this.options.blend){return smBlendedMarginSizes[n];}else if(this.options.compact){return compactMarginSizes[n];}else if(this.options.blend){return blendedMarginSizes[n];}else{return marginSizes[n];}},_borderSize:function(n){var transparentBorderSizes=[5,3,2,1];var blendedBorderSizes=[2,1,1,1];var compactBorderSizes=[1,0];var actualBorderSizes=[0,2,0,0];if(this.options.compact&&(this.options.blend||this._isTransparent())){return 1;}else if(this.options.compact){return compactBorderSizes[n];}else if(this.options.blend){return blendedBorderSizes[n];}else if(this.options.border){return actualBorderSizes[n];}else if(this._isTransparent()){return transparentBorderSizes[n];}
+return 0;},_hasString:function(str){for(var i=1;i<arguments.length;i++)if(str.indexOf(arguments[i])>=0){return true;}return false;},_blend:function(c1,c2){var cc1=OpenLayers.Rico.Color.createFromHex(c1);cc1.blend(OpenLayers.Rico.Color.createFromHex(c2));return cc1;},_background:function(el){try{return OpenLayers.Rico.Color.createColorFromBackground(el).asHex();}catch(err){return"#ffffff";}},_isTransparent:function(){return this.options.color=="transparent";},_isTopRounded:function(){return this._hasString(this.options.corners,"all","top","tl","tr");},_isBottomRounded:function(){return this._hasString(this.options.corners,"all","bottom","bl","br");},_hasSingleTextChild:function(el){return el.childNodes.length==1&&el.childNodes[0].nodeType==3;}};(function(){if(window.google&&google.gears){return;}
+var factory=null;if(typeof GearsFactory!='undefined'){factory=new GearsFactory();}else{try{factory=new ActiveXObject('Gears.Factory');if(factory.getBuildInfo().indexOf('ie_mobile')!=-1){factory.privateSetGlobalObject(this);}}catch(e){if((typeof navigator.mimeTypes!='undefined')&&navigator.mimeTypes["application/x-googlegears"]){factory=document.createElement("object");factory.style.display="none";factory.width=0;factory.height=0;factory.type="application/x-googlegears";document.documentElement.appendChild(factory);}}}
+if(!factory){return;}
+if(!window.google){google={};}
+if(!google.gears){google.gears={factory:factory};}})();OpenLayers.Element={visible:function(element){return OpenLayers.Util.getElement(element).style.display!='none';},toggle:function(){for(var i=0,len=arguments.length;i<len;i++){var element=OpenLayers.Util.getElement(arguments[i]);var display=OpenLayers.Element.visible(element)?'hide':'show';OpenLayers.Element[display](element);}},hide:function(){for(var i=0,len=arguments.length;i<len;i++){var element=OpenLayers.Util.getElement(arguments[i]);if(element){element.style.display='none';}}},show:function(){for(var i=0,len=arguments.length;i<len;i++){var element=OpenLayers.Util.getElement(arguments[i]);if(element){element.style.display='';}}},remove:function(element){element=OpenLayers.Util.getElement(element);element.parentNode.removeChild(element);},getHeight:function(element){element=OpenLayers.Util.getElement(element);return element.offsetHeight;},getDimensions:function(element){element=OpenLayers.Util.getElement(element);if(OpenLayers.Element.getStyle(element,'display')!='none'){return{width:element.offsetWidth,height:element.offsetHeight};}
+var els=element.style;var originalVisibility=els.visibility;var originalPosition=els.position;var originalDisplay=els.display;els.visibility='hidden';els.position='absolute';els.display='';var originalWidth=element.clientWidth;var originalHeight=element.clientHeight;els.display=originalDisplay;els.position=originalPosition;els.visibility=originalVisibility;return{width:originalWidth,height:originalHeight};},hasClass:function(element,name){var names=element.className;return(!!names&&new RegExp("(^|\\s)"+name+"(\\s|$)").test(names));},addClass:function(element,name){if(!OpenLayers.Element.hasClass(element,name)){element.className+=(element.className?" ":"")+name;}
+return element;},removeClass:function(element,name){var names=element.className;if(names){element.className=OpenLayers.String.trim(names.replace(new RegExp("(^|\\s+)"+name+"(\\s+|$)")," "));}
+return element;},toggleClass:function(element,name){if(OpenLayers.Element.hasClass(element,name)){OpenLayers.Element.removeClass(element,name);}else{OpenLayers.Element.addClass(element,name);}
+return element;},getStyle:function(element,style){element=OpenLayers.Util.getElement(element);var value=null;if(element&&element.style){value=element.style[OpenLayers.String.camelize(style)];if(!value){if(document.defaultView&&document.defaultView.getComputedStyle){var css=document.defaultView.getComputedStyle(element,null);value=css?css.getPropertyValue(style):null;}else if(element.currentStyle){value=element.currentStyle[OpenLayers.String.camelize(style)];}}
+var positions=['left','top','right','bottom'];if(window.opera&&(OpenLayers.Util.indexOf(positions,style)!=-1)&&(OpenLayers.Element.getStyle(element,'position')=='static')){value='auto';}}
+return value=='auto'?null:value;}};OpenLayers.Size=OpenLayers.Class({w:0.0,h:0.0,initialize:function(w,h){this.w=parseFloat(w);this.h=parseFloat(h);},toString:function(){return("w="+this.w+",h="+this.h);},clone:function(){return new OpenLayers.Size(this.w,this.h);},equals:function(sz){var equals=false;if(sz!=null){equals=((this.w==sz.w&&this.h==sz.h)||(isNaN(this.w)&&isNaN(this.h)&&isNaN(sz.w)&&isNaN(sz.h)));}
+return equals;},CLASS_NAME:"OpenLayers.Size"});OpenLayers.Console={log:function(){},debug:function(){},info:function(){},warn:function(){},error:function(){},userError:function(error){alert(error);},assert:function(){},dir:function(){},dirxml:function(){},trace:function(){},group:function(){},groupEnd:function(){},time:function(){},timeEnd:function(){},profile:function(){},profileEnd:function(){},count:function(){},CLASS_NAME:"OpenLayers.Console"};(function(){var scripts=document.getElementsByTagName("script");for(var i=0,len=scripts.length;i<len;++i){if(scripts[i].src.indexOf("firebug.js")!=-1){if(console){OpenLayers.Util.extend(OpenLayers.Console,console);break;}}}})();OpenLayers.Icon=OpenLayers.Class({url:null,size:null,offset:null,calculateOffset:null,imageDiv:null,px:null,initialize:function(url,size,offset,calculateOffset){this.url=url;this.size=(size)?size:new OpenLayers.Size(20,20);this.offset=offset?offset:new OpenLayers.Pixel(-(this.size.w/2),-(this.size.h/2));this.calculateOffset=calculateOffset;var id=OpenLayers.Util.createUniqueID("OL_Icon_");this.imageDiv=OpenLayers.Util.createAlphaImageDiv(id);},destroy:function(){this.erase();OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild);this.imageDiv.innerHTML="";this.imageDiv=null;},clone:function(){return new OpenLayers.Icon(this.url,this.size,this.offset,this.calculateOffset);},setSize:function(size){if(size!=null){this.size=size;}
+this.draw();},setUrl:function(url){if(url!=null){this.url=url;}
+this.draw();},draw:function(px){OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,null,this.size,this.url,"absolute");this.moveTo(px);return this.imageDiv;},erase:function(){if(this.imageDiv!=null&&this.imageDiv.parentNode!=null){OpenLayers.Element.remove(this.imageDiv);}},setOpacity:function(opacity){OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,null,null,null,null,null,null,opacity);},moveTo:function(px){if(px!=null){this.px=px;}
+if(this.imageDiv!=null){if(this.px==null){this.display(false);}else{if(this.calculateOffset){this.offset=this.calculateOffset(this.size);}
+var offsetPx=this.px.offset(this.offset);OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,offsetPx);}}},display:function(display){this.imageDiv.style.display=(display)?"":"none";},isDrawn:function(){var isDrawn=(this.imageDiv&&this.imageDiv.parentNode&&(this.imageDiv.parentNode.nodeType!=11));return isDrawn;},CLASS_NAME:"OpenLayers.Icon"});OpenLayers.Popup=OpenLayers.Class({events:null,id:"",lonlat:null,div:null,contentSize:null,size:null,contentHTML:null,backgroundColor:"",opacity:"",border:"",contentDiv:null,groupDiv:null,closeDiv:null,autoSize:false,minSize:null,maxSize:null,displayClass:"olPopup",contentDisplayClass:"olPopupContent",padding:0,disableFirefoxOverflowHack:false,fixPadding:function(){if(typeof this.padding=="number"){this.padding=new OpenLayers.Bounds(this.padding,this.padding,this.padding,this.padding);}},panMapIfOutOfView:false,keepInMap:false,closeOnMove:false,map:null,initialize:function(id,lonlat,contentSize,contentHTML,closeBox,closeBoxCallback){if(id==null){id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");}
+this.id=id;this.lonlat=lonlat;this.contentSize=(contentSize!=null)?contentSize:new OpenLayers.Size(OpenLayers.Popup.WIDTH,OpenLayers.Popup.HEIGHT);if(contentHTML!=null){this.contentHTML=contentHTML;}
+this.backgroundColor=OpenLayers.Popup.COLOR;this.opacity=OpenLayers.Popup.OPACITY;this.border=OpenLayers.Popup.BORDER;this.div=OpenLayers.Util.createDiv(this.id,null,null,null,null,null,"hidden");this.div.className=this.displayClass;var groupDivId=this.id+"_GroupDiv";this.groupDiv=OpenLayers.Util.createDiv(groupDivId,null,null,null,"relative",null,"hidden");var id=this.div.id+"_contentDiv";this.contentDiv=OpenLayers.Util.createDiv(id,null,this.contentSize.clone(),null,"relative");this.contentDiv.className=this.contentDisplayClass;this.groupDiv.appendChild(this.contentDiv);this.div.appendChild(this.groupDiv);if(closeBox){this.addCloseBox(closeBoxCallback);}
+this.registerEvents();},destroy:function(){this.id=null;this.lonlat=null;this.size=null;this.contentHTML=null;this.backgroundColor=null;this.opacity=null;this.border=null;if(this.closeOnMove&&this.map){this.map.events.unregister("movestart",this,this.hide);}
+this.events.destroy();this.events=null;if(this.closeDiv){OpenLayers.Event.stopObservingElement(this.closeDiv);this.groupDiv.removeChild(this.closeDiv);}
+this.closeDiv=null;this.div.removeChild(this.groupDiv);this.groupDiv=null;if(this.map!=null){this.map.removePopup(this);}
+this.map=null;this.div=null;this.autoSize=null;this.minSize=null;this.maxSize=null;this.padding=null;this.panMapIfOutOfView=null;},draw:function(px){if(px==null){if((this.lonlat!=null)&&(this.map!=null)){px=this.map.getLayerPxFromLonLat(this.lonlat);}}
+if(this.closeOnMove){this.map.events.register("movestart",this,this.hide);}
+if(!this.disableFirefoxOverflowHack&&OpenLayers.Util.getBrowserName()=='firefox'){this.map.events.register("movestart",this,function(){var style=document.defaultView.getComputedStyle(this.contentDiv,null);var currentOverflow=style.getPropertyValue("overflow");if(currentOverflow!="hidden"){this.contentDiv._oldOverflow=currentOverflow;this.contentDiv.style.overflow="hidden";}});this.map.events.register("moveend",this,function(){var oldOverflow=this.contentDiv._oldOverflow;if(oldOverflow){this.contentDiv.style.overflow=oldOverflow;this.contentDiv._oldOverflow=null;}});}
+this.moveTo(px);if(!this.autoSize&&!this.size){this.setSize(this.contentSize);}
+this.setBackgroundColor();this.setOpacity();this.setBorder();this.setContentHTML();if(this.panMapIfOutOfView){this.panIntoView();}
+return this.div;},updatePosition:function(){if((this.lonlat)&&(this.map)){var px=this.map.getLayerPxFromLonLat(this.lonlat);if(px){this.moveTo(px);}}},moveTo:function(px){if((px!=null)&&(this.div!=null)){this.div.style.left=px.x+"px";this.div.style.top=px.y+"px";}},visible:function(){return OpenLayers.Element.visible(this.div);},toggle:function(){if(this.visible()){this.hide();}else{this.show();}},show:function(){OpenLayers.Element.show(this.div);if(this.panMapIfOutOfView){this.panIntoView();}},hide:function(){OpenLayers.Element.hide(this.div);},setSize:function(contentSize){this.size=contentSize.clone();var contentDivPadding=this.getContentDivPadding();var wPadding=contentDivPadding.left+contentDivPadding.right;var hPadding=contentDivPadding.top+contentDivPadding.bottom;this.fixPadding();wPadding+=this.padding.left+this.padding.right;hPadding+=this.padding.top+this.padding.bottom;if(this.closeDiv){var closeDivWidth=parseInt(this.closeDiv.style.width);wPadding+=closeDivWidth+contentDivPadding.right;}
+this.size.w+=wPadding;this.size.h+=hPadding;if(OpenLayers.Util.getBrowserName()=="msie"){this.contentSize.w+=contentDivPadding.left+contentDivPadding.right;this.contentSize.h+=contentDivPadding.bottom+contentDivPadding.top;}
+if(this.div!=null){this.div.style.width=this.size.w+"px";this.div.style.height=this.size.h+"px";}
+if(this.contentDiv!=null){this.contentDiv.style.width=contentSize.w+"px";this.contentDiv.style.height=contentSize.h+"px";}},updateSize:function(){var preparedHTML="<div class='"+this.contentDisplayClass+"'>"+
+this.contentDiv.innerHTML+"</div>";var containerElement=(this.map)?this.map.layerContainerDiv:document.body;var realSize=OpenLayers.Util.getRenderedDimensions(preparedHTML,null,{displayClass:this.displayClass,containerElement:containerElement});var safeSize=this.getSafeContentSize(realSize);var newSize=null;if(safeSize.equals(realSize)){newSize=realSize;}else{var fixedSize=new OpenLayers.Size();fixedSize.w=(safeSize.w<realSize.w)?safeSize.w:null;fixedSize.h=(safeSize.h<realSize.h)?safeSize.h:null;if(fixedSize.w&&fixedSize.h){newSize=safeSize;}else{var clippedSize=OpenLayers.Util.getRenderedDimensions(preparedHTML,fixedSize,{displayClass:this.contentDisplayClass,containerElement:containerElement});var currentOverflow=OpenLayers.Element.getStyle(this.contentDiv,"overflow");if((currentOverflow!="hidden")&&(clippedSize.equals(safeSize))){var scrollBar=OpenLayers.Util.getScrollbarWidth();if(fixedSize.w){clippedSize.h+=scrollBar;}else{clippedSize.w+=scrollBar;}}
+newSize=this.getSafeContentSize(clippedSize);}}
+this.setSize(newSize);},setBackgroundColor:function(color){if(color!=undefined){this.backgroundColor=color;}
+if(this.div!=null){this.div.style.backgroundColor=this.backgroundColor;}},setOpacity:function(opacity){if(opacity!=undefined){this.opacity=opacity;}
+if(this.div!=null){this.div.style.opacity=this.opacity;this.div.style.filter='alpha(opacity='+this.opacity*100+')';}},setBorder:function(border){if(border!=undefined){this.border=border;}
+if(this.div!=null){this.div.style.border=this.border;}},setContentHTML:function(contentHTML){if(contentHTML!=null){this.contentHTML=contentHTML;}
+if((this.contentDiv!=null)&&(this.contentHTML!=null)&&(this.contentHTML!=this.contentDiv.innerHTML)){this.contentDiv.innerHTML=this.contentHTML;if(this.autoSize){this.registerImageListeners();this.updateSize();}}},registerImageListeners:function(){var onImgLoad=function(){this.popup.updateSize();if(this.popup.visible()&&this.popup.panMapIfOutOfView){this.popup.panIntoView();}
+OpenLayers.Event.stopObserving(this.img,"load",this.img._onImageLoad);};var images=this.contentDiv.getElementsByTagName("img");for(var i=0,len=images.length;i<len;i++){var img=images[i];if(img.width==0||img.height==0){var context={'popup':this,'img':img};img._onImgLoad=OpenLayers.Function.bind(onImgLoad,context);OpenLayers.Event.observe(img,'load',img._onImgLoad);}}},getSafeContentSize:function(size){var safeContentSize=size.clone();var contentDivPadding=this.getContentDivPadding();var wPadding=contentDivPadding.left+contentDivPadding.right;var hPadding=contentDivPadding.top+contentDivPadding.bottom;this.fixPadding();wPadding+=this.padding.left+this.padding.right;hPadding+=this.padding.top+this.padding.bottom;if(this.closeDiv){var closeDivWidth=parseInt(this.closeDiv.style.width);wPadding+=closeDivWidth+contentDivPadding.right;}
+if(this.minSize){safeContentSize.w=Math.max(safeContentSize.w,(this.minSize.w-wPadding));safeContentSize.h=Math.max(safeContentSize.h,(this.minSize.h-hPadding));}
+if(this.maxSize){safeContentSize.w=Math.min(safeContentSize.w,(this.maxSize.w-wPadding));safeContentSize.h=Math.min(safeContentSize.h,(this.maxSize.h-hPadding));}
+if(this.map&&this.map.size){var extraX=0,extraY=0;if(this.keepInMap&&!this.panMapIfOutOfView){var px=this.map.getPixelFromLonLat(this.lonlat);switch(this.relativePosition){case"tr":extraX=px.x;extraY=this.map.size.h-px.y;break;case"tl":extraX=this.map.size.w-px.x;extraY=this.map.size.h-px.y;break;case"bl":extraX=this.map.size.w-px.x;extraY=px.y;break;case"br":extraX=px.x;extraY=px.y;break;default:extraX=px.x;extraY=this.map.size.h-px.y;break;}}
+var maxY=this.map.size.h-
+this.map.paddingForPopups.top-
+this.map.paddingForPopups.bottom-
+hPadding-extraY;var maxX=this.map.size.w-
+this.map.paddingForPopups.left-
+this.map.paddingForPopups.right-
+wPadding-extraX;safeContentSize.w=Math.min(safeContentSize.w,maxX);safeContentSize.h=Math.min(safeContentSize.h,maxY);}
+return safeContentSize;},getContentDivPadding:function(){var contentDivPadding=this._contentDivPadding;if(!contentDivPadding){if(this.div.parentNode==null){this.div.style.display="none";document.body.appendChild(this.div);}
+contentDivPadding=new OpenLayers.Bounds(OpenLayers.Element.getStyle(this.contentDiv,"padding-left"),OpenLayers.Element.getStyle(this.contentDiv,"padding-bottom"),OpenLayers.Element.getStyle(this.contentDiv,"padding-right"),OpenLayers.Element.getStyle(this.contentDiv,"padding-top"));this._contentDivPadding=contentDivPadding;if(this.div.parentNode==document.body){document.body.removeChild(this.div);this.div.style.display="";}}
+return contentDivPadding;},addCloseBox:function(callback){this.closeDiv=OpenLayers.Util.createDiv(this.id+"_close",null,new OpenLayers.Size(17,17));this.closeDiv.className="olPopupCloseBox";var contentDivPadding=this.getContentDivPadding();this.closeDiv.style.right=contentDivPadding.right+"px";this.closeDiv.style.top=contentDivPadding.top+"px";this.groupDiv.appendChild(this.closeDiv);var closePopup=callback||function(e){this.hide();OpenLayers.Event.stop(e);};OpenLayers.Event.observe(this.closeDiv,"click",OpenLayers.Function.bindAsEventListener(closePopup,this));},panIntoView:function(){var mapSize=this.map.getSize();var origTL=this.map.getViewPortPxFromLayerPx(new OpenLayers.Pixel(parseInt(this.div.style.left),parseInt(this.div.style.top)));var newTL=origTL.clone();if(origTL.x<this.map.paddingForPopups.left){newTL.x=this.map.paddingForPopups.left;}else
+if((origTL.x+this.size.w)>(mapSize.w-this.map.paddingForPopups.right)){newTL.x=mapSize.w-this.map.paddingForPopups.right-this.size.w;}
+if(origTL.y<this.map.paddingForPopups.top){newTL.y=this.map.paddingForPopups.top;}else
+if((origTL.y+this.size.h)>(mapSize.h-this.map.paddingForPopups.bottom)){newTL.y=mapSize.h-this.map.paddingForPopups.bottom-this.size.h;}
+var dx=origTL.x-newTL.x;var dy=origTL.y-newTL.y;this.map.pan(dx,dy);},registerEvents:function(){this.events=new OpenLayers.Events(this,this.div,null,true);this.events.on({"mousedown":this.onmousedown,"mousemove":this.onmousemove,"mouseup":this.onmouseup,"click":this.onclick,"mouseout":this.onmouseout,"dblclick":this.ondblclick,scope:this});},onmousedown:function(evt){this.mousedown=true;OpenLayers.Event.stop(evt,true);},onmousemove:function(evt){if(this.mousedown){OpenLayers.Event.stop(evt,true);}},onmouseup:function(evt){if(this.mousedown){this.mousedown=false;OpenLayers.Event.stop(evt,true);}},onclick:function(evt){OpenLayers.Event.stop(evt,true);},onmouseout:function(evt){this.mousedown=false;},ondblclick:function(evt){OpenLayers.Event.stop(evt,true);},CLASS_NAME:"OpenLayers.Popup"});OpenLayers.Popup.WIDTH=200;OpenLayers.Popup.HEIGHT=200;OpenLayers.Popup.COLOR="white";OpenLayers.Popup.OPACITY=1;OpenLayers.Popup.BORDER="0px";OpenLayers.Protocol=OpenLayers.Class({format:null,options:null,autoDestroy:true,defaultFilter:null,initialize:function(options){options=options||{};OpenLayers.Util.extend(this,options);this.options=options;},mergeWithDefaultFilter:function(filter){var merged;if(filter&&this.defaultFilter){merged=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND,filters:[this.defaultFilter,filter]});}else{merged=filter||this.defaultFilter||undefined;}
+return merged;},destroy:function(){this.options=null;this.format=null;},read:function(options){options=options||{};options.filter=this.mergeWithDefaultFilter(options.filter);},create:function(){},update:function(){},"delete":function(){},commit:function(){},abort:function(response){},createCallback:function(method,response,options){return OpenLayers.Function.bind(function(){method.apply(this,[response,options]);},this);},CLASS_NAME:"OpenLayers.Protocol"});OpenLayers.Protocol.Response=OpenLayers.Class({code:null,requestType:null,last:true,features:null,reqFeatures:null,priv:null,initialize:function(options){OpenLayers.Util.extend(this,options);},success:function(){return this.code>0;},CLASS_NAME:"OpenLayers.Protocol.Response"});OpenLayers.Protocol.Response.SUCCESS=1;OpenLayers.Protocol.Response.FAILURE=0;OpenLayers.Renderer=OpenLayers.Class({container:null,root:null,extent:null,locked:false,size:null,resolution:null,map:null,initialize:function(containerID,options){this.container=OpenLayers.Util.getElement(containerID);},destroy:function(){this.container=null;this.extent=null;this.size=null;this.resolution=null;this.map=null;},supported:function(){return false;},setExtent:function(extent,resolutionChanged){this.extent=extent.clone();if(resolutionChanged){this.resolution=null;}},setSize:function(size){this.size=size.clone();this.resolution=null;},getResolution:function(){this.resolution=this.resolution||this.map.getResolution();return this.resolution;},drawFeature:function(feature,style){if(style==null){style=feature.style;}
+if(feature.geometry){var bounds=feature.geometry.getBounds();if(bounds){if(!bounds.intersectsBounds(this.extent)){style={display:"none"};}
+var rendered=this.drawGeometry(feature.geometry,style,feature.id);if(style.display!="none"&&style.label&&rendered!==false){var location=feature.geometry.getCentroid();if(style.labelXOffset||style.labelYOffset){xOffset=isNaN(style.labelXOffset)?0:style.labelXOffset;yOffset=isNaN(style.labelYOffset)?0:style.labelYOffset;var res=this.getResolution();location.move(xOffset*res,yOffset*res);}
+this.drawText(feature.id,style,location);}else{this.removeText(feature.id);}
+return rendered;}}},drawGeometry:function(geometry,style,featureId){},drawText:function(featureId,style,location){},removeText:function(featureId){},clear:function(){},getFeatureIdFromEvent:function(evt){},eraseFeatures:function(features){if(!(features instanceof Array)){features=[features];}
+for(var i=0,len=features.length;i<len;++i){var feature=features[i];this.eraseGeometry(feature.geometry,feature.id);this.removeText(feature.id);}},eraseGeometry:function(geometry,featureId){},moveRoot:function(renderer){},getRenderLayerId:function(){return this.container.id;},applyDefaultSymbolizer:function(symbolizer){var result=OpenLayers.Util.extend({},OpenLayers.Renderer.defaultSymbolizer);if(symbolizer.stroke===false){delete result.strokeWidth;delete result.strokeColor;}
+if(symbolizer.fill===false){delete result.fillColor;}
+OpenLayers.Util.extend(result,symbolizer);return result;},CLASS_NAME:"OpenLayers.Renderer"});OpenLayers.Renderer.defaultSymbolizer={fillColor:"#000000",strokeColor:"#000000",strokeWidth:2,fillOpacity:1,strokeOpacity:1,pointRadius:0};OpenLayers.Strategy=OpenLayers.Class({layer:null,options:null,active:null,autoActivate:true,autoDestroy:true,initialize:function(options){OpenLayers.Util.extend(this,options);this.options=options;this.active=false;},destroy:function(){this.deactivate();this.layer=null;this.options=null;},setLayer:function(layer){this.layer=layer;},activate:function(){if(!this.active){this.active=true;return true;}
+return false;},deactivate:function(){if(this.active){this.active=false;return true;}
+return false;},CLASS_NAME:"OpenLayers.Strategy"});OpenLayers.Symbolizer=OpenLayers.Class({zIndex:0,initialize:function(config){OpenLayers.Util.extend(this,config);},clone:function(){var Type=eval(this.CLASS_NAME);return new Type(OpenLayers.Util.extend({},this));},CLASS_NAME:"OpenLayers.Symbolizer"});OpenLayers.Rico.Color=OpenLayers.Class({initialize:function(red,green,blue){this.rgb={r:red,g:green,b:blue};},setRed:function(r){this.rgb.r=r;},setGreen:function(g){this.rgb.g=g;},setBlue:function(b){this.rgb.b=b;},setHue:function(h){var hsb=this.asHSB();hsb.h=h;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,hsb.b);},setSaturation:function(s){var hsb=this.asHSB();hsb.s=s;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,hsb.b);},setBrightness:function(b){var hsb=this.asHSB();hsb.b=b;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,hsb.b);},darken:function(percent){var hsb=this.asHSB();this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,Math.max(hsb.b-percent,0));},brighten:function(percent){var hsb=this.asHSB();this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,Math.min(hsb.b+percent,1));},blend:function(other){this.rgb.r=Math.floor((this.rgb.r+other.rgb.r)/2);this.rgb.g=Math.floor((this.rgb.g+other.rgb.g)/2);this.rgb.b=Math.floor((this.rgb.b+other.rgb.b)/2);},isBright:function(){var hsb=this.asHSB();return this.asHSB().b>0.5;},isDark:function(){return!this.isBright();},asRGB:function(){return"rgb("+this.rgb.r+","+this.rgb.g+","+this.rgb.b+")";},asHex:function(){return"#"+this.rgb.r.toColorPart()+this.rgb.g.toColorPart()+this.rgb.b.toColorPart();},asHSB:function(){return OpenLayers.Rico.Color.RGBtoHSB(this.rgb.r,this.rgb.g,this.rgb.b);},toString:function(){return this.asHex();}});OpenLayers.Rico.Color.createFromHex=function(hexCode){if(hexCode.length==4){var shortHexCode=hexCode;var hexCode='#';for(var i=1;i<4;i++){hexCode+=(shortHexCode.charAt(i)+
+shortHexCode.charAt(i));}}
+if(hexCode.indexOf('#')==0){hexCode=hexCode.substring(1);}
+var red=hexCode.substring(0,2);var green=hexCode.substring(2,4);var blue=hexCode.substring(4,6);return new OpenLayers.Rico.Color(parseInt(red,16),parseInt(green,16),parseInt(blue,16));};OpenLayers.Rico.Color.createColorFromBackground=function(elem){var actualColor=RicoUtil.getElementsComputedStyle(OpenLayers.Util.getElement(elem),"backgroundColor","background-color");if(actualColor=="transparent"&&elem.parentNode){return OpenLayers.Rico.Color.createColorFromBackground(elem.parentNode);}
+if(actualColor==null){return new OpenLayers.Rico.Color(255,255,255);}
+if(actualColor.indexOf("rgb(")==0){var colors=actualColor.substring(4,actualColor.length-1);var colorArray=colors.split(",");return new OpenLayers.Rico.Color(parseInt(colorArray[0]),parseInt(colorArray[1]),parseInt(colorArray[2]));}
+else if(actualColor.indexOf("#")==0){return OpenLayers.Rico.Color.createFromHex(actualColor);}
+else{return new OpenLayers.Rico.Color(255,255,255);}};OpenLayers.Rico.Color.HSBtoRGB=function(hue,saturation,brightness){var red=0;var green=0;var blue=0;if(saturation==0){red=parseInt(brightness*255.0+0.5);green=red;blue=red;}
+else{var h=(hue-Math.floor(hue))*6.0;var f=h-Math.floor(h);var p=brightness*(1.0-saturation);var q=brightness*(1.0-saturation*f);var t=brightness*(1.0-(saturation*(1.0-f)));switch(parseInt(h)){case 0:red=(brightness*255.0+0.5);green=(t*255.0+0.5);blue=(p*255.0+0.5);break;case 1:red=(q*255.0+0.5);green=(brightness*255.0+0.5);blue=(p*255.0+0.5);break;case 2:red=(p*255.0+0.5);green=(brightness*255.0+0.5);blue=(t*255.0+0.5);break;case 3:red=(p*255.0+0.5);green=(q*255.0+0.5);blue=(brightness*255.0+0.5);break;case 4:red=(t*255.0+0.5);green=(p*255.0+0.5);blue=(brightness*255.0+0.5);break;case 5:red=(brightness*255.0+0.5);green=(p*255.0+0.5);blue=(q*255.0+0.5);break;}}
+return{r:parseInt(red),g:parseInt(green),b:parseInt(blue)};};OpenLayers.Rico.Color.RGBtoHSB=function(r,g,b){var hue;var saturation;var brightness;var cmax=(r>g)?r:g;if(b>cmax){cmax=b;}
+var cmin=(r<g)?r:g;if(b<cmin){cmin=b;}
+brightness=cmax/255.0;if(cmax!=0){saturation=(cmax-cmin)/cmax;}else{saturation=0;}
+if(saturation==0){hue=0;}else{var redc=(cmax-r)/(cmax-cmin);var greenc=(cmax-g)/(cmax-cmin);var bluec=(cmax-b)/(cmax-cmin);if(r==cmax){hue=bluec-greenc;}else if(g==cmax){hue=2.0+redc-bluec;}else{hue=4.0+greenc-redc;}
+hue=hue/6.0;if(hue<0){hue=hue+1.0;}}
+return{h:hue,s:saturation,b:brightness};};OpenLayers.Bounds=OpenLayers.Class({left:null,bottom:null,right:null,top:null,centerLonLat:null,initialize:function(left,bottom,right,top){if(left!=null){this.left=OpenLayers.Util.toFloat(left);}
+if(bottom!=null){this.bottom=OpenLayers.Util.toFloat(bottom);}
+if(right!=null){this.right=OpenLayers.Util.toFloat(right);}
+if(top!=null){this.top=OpenLayers.Util.toFloat(top);}},clone:function(){return new OpenLayers.Bounds(this.left,this.bottom,this.right,this.top);},equals:function(bounds){var equals=false;if(bounds!=null){equals=((this.left==bounds.left)&&(this.right==bounds.right)&&(this.top==bounds.top)&&(this.bottom==bounds.bottom));}
+return equals;},toString:function(){return("left-bottom=("+this.left+","+this.bottom+")"
++" right-top=("+this.right+","+this.top+")");},toArray:function(reverseAxisOrder){if(reverseAxisOrder===true){return[this.bottom,this.left,this.top,this.right];}else{return[this.left,this.bottom,this.right,this.top];}},toBBOX:function(decimal,reverseAxisOrder){if(decimal==null){decimal=6;}
+var mult=Math.pow(10,decimal);var xmin=Math.round(this.left*mult)/mult;var ymin=Math.round(this.bottom*mult)/mult;var xmax=Math.round(this.right*mult)/mult;var ymax=Math.round(this.top*mult)/mult;if(reverseAxisOrder===true){return ymin+","+xmin+","+ymax+","+xmax;}else{return xmin+","+ymin+","+xmax+","+ymax;}},toGeometry:function(){return new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([new OpenLayers.Geometry.Point(this.left,this.bottom),new OpenLayers.Geometry.Point(this.right,this.bottom),new OpenLayers.Geometry.Point(this.right,this.top),new OpenLayers.Geometry.Point(this.left,this.top)])]);},getWidth:function(){return(this.right-this.left);},getHeight:function(){return(this.top-this.bottom);},getSize:function(){return new OpenLayers.Size(this.getWidth(),this.getHeight());},getCenterPixel:function(){return new OpenLayers.Pixel((this.left+this.right)/2,(this.bottom+this.top)/2);},getCenterLonLat:function(){if(!this.centerLonLat){this.centerLonLat=new OpenLayers.LonLat((this.left+this.right)/2,(this.bottom+this.top)/2);}
+return this.centerLonLat;},scale:function(ratio,origin){if(origin==null){origin=this.getCenterLonLat();}
+var origx,origy;if(origin.CLASS_NAME=="OpenLayers.LonLat"){origx=origin.lon;origy=origin.lat;}else{origx=origin.x;origy=origin.y;}
+var left=(this.left-origx)*ratio+origx;var bottom=(this.bottom-origy)*ratio+origy;var right=(this.right-origx)*ratio+origx;var top=(this.top-origy)*ratio+origy;return new OpenLayers.Bounds(left,bottom,right,top);},add:function(x,y){if((x==null)||(y==null)){var msg=OpenLayers.i18n("boundsAddError");OpenLayers.Console.error(msg);return null;}
+return new OpenLayers.Bounds(this.left+x,this.bottom+y,this.right+x,this.top+y);},extend:function(object){var bounds=null;if(object){switch(object.CLASS_NAME){case"OpenLayers.LonLat":bounds=new OpenLayers.Bounds(object.lon,object.lat,object.lon,object.lat);break;case"OpenLayers.Geometry.Point":bounds=new OpenLayers.Bounds(object.x,object.y,object.x,object.y);break;case"OpenLayers.Bounds":bounds=object;break;}
+if(bounds){this.centerLonLat=null;if((this.left==null)||(bounds.left<this.left)){this.left=bounds.left;}
+if((this.bottom==null)||(bounds.bottom<this.bottom)){this.bottom=bounds.bottom;}
+if((this.right==null)||(bounds.right>this.right)){this.right=bounds.right;}
+if((this.top==null)||(bounds.top>this.top)){this.top=bounds.top;}}}},containsLonLat:function(ll,inclusive){return this.contains(ll.lon,ll.lat,inclusive);},containsPixel:function(px,inclusive){return this.contains(px.x,px.y,inclusive);},contains:function(x,y,inclusive){if(inclusive==null){inclusive=true;}
+if(x==null||y==null){return false;}
+x=OpenLayers.Util.toFloat(x);y=OpenLayers.Util.toFloat(y);var contains=false;if(inclusive){contains=((x>=this.left)&&(x<=this.right)&&(y>=this.bottom)&&(y<=this.top));}else{contains=((x>this.left)&&(x<this.right)&&(y>this.bottom)&&(y<this.top));}
+return contains;},intersectsBounds:function(bounds,inclusive){if(inclusive==null){inclusive=true;}
+var intersects=false;var mightTouch=(this.left==bounds.right||this.right==bounds.left||this.top==bounds.bottom||this.bottom==bounds.top);if(inclusive||!mightTouch){var inBottom=(((bounds.bottom>=this.bottom)&&(bounds.bottom<=this.top))||((this.bottom>=bounds.bottom)&&(this.bottom<=bounds.top)));var inTop=(((bounds.top>=this.bottom)&&(bounds.top<=this.top))||((this.top>bounds.bottom)&&(this.top<bounds.top)));var inLeft=(((bounds.left>=this.left)&&(bounds.left<=this.right))||((this.left>=bounds.left)&&(this.left<=bounds.right)));var inRight=(((bounds.right>=this.left)&&(bounds.right<=this.right))||((this.right>=bounds.left)&&(this.right<=bounds.right)));intersects=((inBottom||inTop)&&(inLeft||inRight));}
+return intersects;},containsBounds:function(bounds,partial,inclusive){if(partial==null){partial=false;}
+if(inclusive==null){inclusive=true;}
+var bottomLeft=this.contains(bounds.left,bounds.bottom,inclusive);var bottomRight=this.contains(bounds.right,bounds.bottom,inclusive);var topLeft=this.contains(bounds.left,bounds.top,inclusive);var topRight=this.contains(bounds.right,bounds.top,inclusive);return(partial)?(bottomLeft||bottomRight||topLeft||topRight):(bottomLeft&&bottomRight&&topLeft&&topRight);},determineQuadrant:function(lonlat){var quadrant="";var center=this.getCenterLonLat();quadrant+=(lonlat.lat<center.lat)?"b":"t";quadrant+=(lonlat.lon<center.lon)?"l":"r";return quadrant;},transform:function(source,dest){this.centerLonLat=null;var ll=OpenLayers.Projection.transform({'x':this.left,'y':this.bottom},source,dest);var lr=OpenLayers.Projection.transform({'x':this.right,'y':this.bottom},source,dest);var ul=OpenLayers.Projection.transform({'x':this.left,'y':this.top},source,dest);var ur=OpenLayers.Projection.transform({'x':this.right,'y':this.top},source,dest);this.left=Math.min(ll.x,ul.x);this.bottom=Math.min(ll.y,lr.y);this.right=Math.max(lr.x,ur.x);this.top=Math.max(ul.y,ur.y);return this;},wrapDateLine:function(maxExtent,options){options=options||{};var leftTolerance=options.leftTolerance||0;var rightTolerance=options.rightTolerance||0;var newBounds=this.clone();if(maxExtent){while(newBounds.left<maxExtent.left&&(newBounds.right-rightTolerance)<=maxExtent.left){newBounds=newBounds.add(maxExtent.getWidth(),0);}
+while((newBounds.left+leftTolerance)>=maxExtent.right&&newBounds.right>maxExtent.right){newBounds=newBounds.add(-maxExtent.getWidth(),0);}}
+return newBounds;},CLASS_NAME:"OpenLayers.Bounds"});OpenLayers.Bounds.fromString=function(str){var bounds=str.split(",");return OpenLayers.Bounds.fromArray(bounds);};OpenLayers.Bounds.fromArray=function(bbox){return new OpenLayers.Bounds(parseFloat(bbox[0]),parseFloat(bbox[1]),parseFloat(bbox[2]),parseFloat(bbox[3]));};OpenLayers.Bounds.fromSize=function(size){return new OpenLayers.Bounds(0,size.h,size.w,0);};OpenLayers.Bounds.oppositeQuadrant=function(quadrant){var opp="";opp+=(quadrant.charAt(0)=='t')?'b':'t';opp+=(quadrant.charAt(1)=='l')?'r':'l';return opp;};OpenLayers.LonLat=OpenLayers.Class({lon:0.0,lat:0.0,initialize:function(lon,lat){this.lon=OpenLayers.Util.toFloat(lon);this.lat=OpenLayers.Util.toFloat(lat);},toString:function(){return("lon="+this.lon+",lat="+this.lat);},toShortString:function(){return(this.lon+", "+this.lat);},clone:function(){return new OpenLayers.LonLat(this.lon,this.lat);},add:function(lon,lat){if((lon==null)||(lat==null)){var msg=OpenLayers.i18n("lonlatAddError");OpenLayers.Console.error(msg);return null;}
+return new OpenLayers.LonLat(this.lon+OpenLayers.Util.toFloat(lon),this.lat+OpenLayers.Util.toFloat(lat));},equals:function(ll){var equals=false;if(ll!=null){equals=((this.lon==ll.lon&&this.lat==ll.lat)||(isNaN(this.lon)&&isNaN(this.lat)&&isNaN(ll.lon)&&isNaN(ll.lat)));}
+return equals;},transform:function(source,dest){var point=OpenLayers.Projection.transform({'x':this.lon,'y':this.lat},source,dest);this.lon=point.x;this.lat=point.y;return this;},wrapDateLine:function(maxExtent){var newLonLat=this.clone();if(maxExtent){while(newLonLat.lon<maxExtent.left){newLonLat.lon+=maxExtent.getWidth();}
+while(newLonLat.lon>maxExtent.right){newLonLat.lon-=maxExtent.getWidth();}}
+return newLonLat;},CLASS_NAME:"OpenLayers.LonLat"});OpenLayers.LonLat.fromString=function(str){var pair=str.split(",");return new OpenLayers.LonLat(pair[0],pair[1]);};OpenLayers.Pixel=OpenLayers.Class({x:0.0,y:0.0,initialize:function(x,y){this.x=parseFloat(x);this.y=parseFloat(y);},toString:function(){return("x="+this.x+",y="+this.y);},clone:function(){return new OpenLayers.Pixel(this.x,this.y);},equals:function(px){var equals=false;if(px!=null){equals=((this.x==px.x&&this.y==px.y)||(isNaN(this.x)&&isNaN(this.y)&&isNaN(px.x)&&isNaN(px.y)));}
+return equals;},add:function(x,y){if((x==null)||(y==null)){var msg=OpenLayers.i18n("pixelAddError");OpenLayers.Console.error(msg);return null;}
+return new OpenLayers.Pixel(this.x+x,this.y+y);},offset:function(px){var newPx=this.clone();if(px){newPx=this.add(px.x,px.y);}
+return newPx;},CLASS_NAME:"OpenLayers.Pixel"});OpenLayers.Control=OpenLayers.Class({id:null,map:null,div:null,type:null,allowSelection:false,displayClass:"",title:"",autoActivate:false,active:null,handler:null,eventListeners:null,events:null,EVENT_TYPES:["activate","deactivate"],initialize:function(options){this.displayClass=this.CLASS_NAME.replace("OpenLayers.","ol").replace(/\./g,"");OpenLayers.Util.extend(this,options);this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);if(this.eventListeners instanceof Object){this.events.on(this.eventListeners);}
+if(this.id==null){this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");}},destroy:function(){if(this.events){if(this.eventListeners){this.events.un(this.eventListeners);}
+this.events.destroy();this.events=null;}
+this.eventListeners=null;if(this.handler){this.handler.destroy();this.handler=null;}
+if(this.handlers){for(var key in this.handlers){if(this.handlers.hasOwnProperty(key)&&typeof this.handlers[key].destroy=="function"){this.handlers[key].destroy();}}
+this.handlers=null;}
+if(this.map){this.map.removeControl(this);this.map=null;}},setMap:function(map){this.map=map;if(this.handler){this.handler.setMap(map);}},draw:function(px){if(this.div==null){this.div=OpenLayers.Util.createDiv(this.id);this.div.className=this.displayClass;if(!this.allowSelection){this.div.className+=" olControlNoSelect";this.div.setAttribute("unselectable","on",0);this.div.onselectstart=OpenLayers.Function.False;}
+if(this.title!=""){this.div.title=this.title;}}
+if(px!=null){this.position=px.clone();}
+this.moveTo(this.position);return this.div;},moveTo:function(px){if((px!=null)&&(this.div!=null)){this.div.style.left=px.x+"px";this.div.style.top=px.y+"px";}},activate:function(){if(this.active){return false;}
+if(this.handler){this.handler.activate();}
+this.active=true;if(this.map){OpenLayers.Element.addClass(this.map.viewPortDiv,this.displayClass.replace(/ /g,"")+"Active");}
+this.events.triggerEvent("activate");return true;},deactivate:function(){if(this.active){if(this.handler){this.handler.deactivate();}
+this.active=false;if(this.map){OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass.replace(/ /g,"")+"Active");}
+this.events.triggerEvent("deactivate");return true;}
+return false;},CLASS_NAME:"OpenLayers.Control"});OpenLayers.Control.TYPE_BUTTON=1;OpenLayers.Control.TYPE_TOGGLE=2;OpenLayers.Control.TYPE_TOOL=3;OpenLayers.Lang={code:null,defaultCode:"en",getCode:function(){if(!OpenLayers.Lang.code){OpenLayers.Lang.setCode();}
+return OpenLayers.Lang.code;},setCode:function(code){var lang;if(!code){code=(OpenLayers.Util.getBrowserName()=="msie")?navigator.userLanguage:navigator.language;}
+var parts=code.split('-');parts[0]=parts[0].toLowerCase();if(typeof OpenLayers.Lang[parts[0]]=="object"){lang=parts[0];}
+if(parts[1]){var testLang=parts[0]+'-'+parts[1].toUpperCase();if(typeof OpenLayers.Lang[testLang]=="object"){lang=testLang;}}
+if(!lang){OpenLayers.Console.warn('Failed to find OpenLayers.Lang.'+parts.join("-")+' dictionary, falling back to default language');lang=OpenLayers.Lang.defaultCode;}
+OpenLayers.Lang.code=lang;},translate:function(key,context){var dictionary=OpenLayers.Lang[OpenLayers.Lang.getCode()];var message=dictionary[key];if(!message){message=key;}
+if(context){message=OpenLayers.String.format(message,context);}
+return message;}};OpenLayers.i18n=OpenLayers.Lang.translate;OpenLayers.Popup.Anchored=OpenLayers.Class(OpenLayers.Popup,{relativePosition:null,keepInMap:true,anchor:null,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){var newArguments=[id,lonlat,contentSize,contentHTML,closeBox,closeBoxCallback];OpenLayers.Popup.prototype.initialize.apply(this,newArguments);this.anchor=(anchor!=null)?anchor:{size:new OpenLayers.Size(0,0),offset:new OpenLayers.Pixel(0,0)};},destroy:function(){this.anchor=null;this.relativePosition=null;OpenLayers.Popup.prototype.destroy.apply(this,arguments);},show:function(){this.updatePosition();OpenLayers.Popup.prototype.show.apply(this,arguments);},moveTo:function(px){var oldRelativePosition=this.relativePosition;this.relativePosition=this.calculateRelativePosition(px);var newPx=this.calculateNewPx(px);var newArguments=new Array(newPx);OpenLayers.Popup.prototype.moveTo.apply(this,newArguments);if(this.relativePosition!=oldRelativePosition){this.updateRelativePosition();}},setSize:function(contentSize){OpenLayers.Popup.prototype.setSize.apply(this,arguments);if((this.lonlat)&&(this.map)){var px=this.map.getLayerPxFromLonLat(this.lonlat);this.moveTo(px);}},calculateRelativePosition:function(px){var lonlat=this.map.getLonLatFromLayerPx(px);var extent=this.map.getExtent();var quadrant=extent.determineQuadrant(lonlat);return OpenLayers.Bounds.oppositeQuadrant(quadrant);},updateRelativePosition:function(){},calculateNewPx:function(px){var newPx=px.offset(this.anchor.offset);var size=this.size||this.contentSize;var top=(this.relativePosition.charAt(0)=='t');newPx.y+=(top)?-(size.h+this.anchor.size.h):this.anchor.size.h;var left=(this.relativePosition.charAt(1)=='l');newPx.x+=(left)?-(size.w+this.anchor.size.w):this.anchor.size.w;return newPx;},CLASS_NAME:"OpenLayers.Popup.Anchored"});OpenLayers.Protocol.SOS=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Protocol.SOS.DEFAULTS);var cls=OpenLayers.Protocol.SOS["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported SOS version: "+options.version;}
+return new cls(options);};OpenLayers.Protocol.SOS.DEFAULTS={"version":"1.0.0"};OpenLayers.Protocol.SQL=OpenLayers.Class(OpenLayers.Protocol,{databaseName:'ol',tableName:"ol_vector_features",postReadFiltering:true,initialize:function(options){OpenLayers.Protocol.prototype.initialize.apply(this,[options]);},destroy:function(){OpenLayers.Protocol.prototype.destroy.apply(this);},supported:function(){return false;},evaluateFilter:function(feature,filter){return filter&&this.postReadFiltering?filter.evaluate(feature):true;},CLASS_NAME:"OpenLayers.Protocol.SQL"});OpenLayers.Protocol.WFS=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Protocol.WFS.DEFAULTS);var cls=OpenLayers.Protocol.WFS["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported WFS version: "+options.version;}
+return new cls(options);};OpenLayers.Protocol.WFS.fromWMSLayer=function(layer,options){var typeName,featurePrefix;var param=layer.params["LAYERS"];var parts=(param instanceof Array?param[0]:param).split(":");if(parts.length>1){featurePrefix=parts[0];}
+typeName=parts.pop();var protocolOptions={url:layer.url,featureType:typeName,featurePrefix:featurePrefix,srsName:layer.projection&&layer.projection.getCode()||layer.map&&layer.map.getProjectionObject().getCode(),version:"1.1.0"};return new OpenLayers.Protocol.WFS(OpenLayers.Util.applyDefaults(options,protocolOptions));};OpenLayers.Protocol.WFS.DEFAULTS={"version":"1.0.0"};OpenLayers.Renderer.Canvas=OpenLayers.Class(OpenLayers.Renderer,{canvas:null,features:null,initialize:function(containerID){OpenLayers.Renderer.prototype.initialize.apply(this,arguments);this.root=document.createElement("canvas");this.container.appendChild(this.root);this.canvas=this.root.getContext("2d");this.features={};},eraseGeometry:function(geometry,featureId){this.eraseFeatures(this.features[featureId][0]);},supported:function(){var canvas=document.createElement("canvas");return!!canvas.getContext;},setExtent:function(extent){this.extent=extent.clone();this.resolution=null;this.redraw();},setSize:function(size){this.size=size.clone();this.root.style.width=size.w+"px";this.root.style.height=size.h+"px";this.root.width=size.w;this.root.height=size.h;this.resolution=null;},drawFeature:function(feature,style){style=style||feature.style;style=this.applyDefaultSymbolizer(style);this.features[feature.id]=[feature,style];this.redraw();},drawGeometry:function(geometry,style){var className=geometry.CLASS_NAME;if((className=="OpenLayers.Geometry.Collection")||(className=="OpenLayers.Geometry.MultiPoint")||(className=="OpenLayers.Geometry.MultiLineString")||(className=="OpenLayers.Geometry.MultiPolygon")){for(var i=0;i<geometry.components.length;i++){this.drawGeometry(geometry.components[i],style);}
+return;}
+switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":this.drawPoint(geometry,style);break;case"OpenLayers.Geometry.LineString":this.drawLineString(geometry,style);break;case"OpenLayers.Geometry.LinearRing":this.drawLinearRing(geometry,style);break;case"OpenLayers.Geometry.Polygon":this.drawPolygon(geometry,style);break;default:break;}},drawExternalGraphic:function(pt,style){var img=new Image();if(style.graphicTitle){img.title=style.graphicTitle;}
+var width=style.graphicWidth||style.graphicHeight;var height=style.graphicHeight||style.graphicWidth;width=width?width:style.pointRadius*2;height=height?height:style.pointRadius*2;var xOffset=(style.graphicXOffset!=undefined)?style.graphicXOffset:-(0.5*width);var yOffset=(style.graphicYOffset!=undefined)?style.graphicYOffset:-(0.5*height);var context={img:img,x:(pt[0]+xOffset),y:(pt[1]+yOffset),width:width,height:height,opacity:style.graphicOpacity||style.fillOpacity,canvas:this.canvas};img.onload=OpenLayers.Function.bind(function(){this.canvas.globalAlpha=this.opacity;this.canvas.drawImage(this.img,this.x,this.y,this.width,this.height);},context);img.src=style.externalGraphic;},setCanvasStyle:function(type,style){if(type=="fill"){this.canvas.globalAlpha=style['fillOpacity'];this.canvas.fillStyle=style['fillColor'];}else if(type=="stroke"){this.canvas.globalAlpha=style['strokeOpacity'];this.canvas.strokeStyle=style['strokeColor'];this.canvas.lineWidth=style['strokeWidth'];}else{this.canvas.globalAlpha=0;this.canvas.lineWidth=1;}},drawPoint:function(geometry,style){if(style.graphic!==false){var pt=this.getLocalXY(geometry);if(style.externalGraphic){this.drawExternalGraphic(pt,style);}else{if(style.fill!==false){this.setCanvasStyle("fill",style);this.canvas.beginPath();this.canvas.arc(pt[0],pt[1],style.pointRadius,0,Math.PI*2,true);this.canvas.fill();}
+if(style.stroke!==false){this.setCanvasStyle("stroke",style);this.canvas.beginPath();this.canvas.arc(pt[0],pt[1],style.pointRadius,0,Math.PI*2,true);this.canvas.stroke();this.setCanvasStyle("reset");}}}},drawLineString:function(geometry,style){if(style.stroke!==false){this.setCanvasStyle("stroke",style);this.canvas.beginPath();var start=this.getLocalXY(geometry.components[0]);this.canvas.moveTo(start[0],start[1]);for(var i=1;i<geometry.components.length;i++){var pt=this.getLocalXY(geometry.components[i]);this.canvas.lineTo(pt[0],pt[1]);}
+this.canvas.stroke();}
+this.setCanvasStyle("reset");},drawLinearRing:function(geometry,style){if(style.fill!==false){this.setCanvasStyle("fill",style);this.canvas.beginPath();var start=this.getLocalXY(geometry.components[0]);this.canvas.moveTo(start[0],start[1]);for(var i=1;i<geometry.components.length-1;i++){var pt=this.getLocalXY(geometry.components[i]);this.canvas.lineTo(pt[0],pt[1]);}
+this.canvas.fill();}
+if(style.stroke!==false){this.setCanvasStyle("stroke",style);this.canvas.beginPath();var start=this.getLocalXY(geometry.components[0]);this.canvas.moveTo(start[0],start[1]);for(var i=1;i<geometry.components.length;i++){var pt=this.getLocalXY(geometry.components[i]);this.canvas.lineTo(pt[0],pt[1]);}
+this.canvas.stroke();}
+this.setCanvasStyle("reset");},drawPolygon:function(geometry,style){this.drawLinearRing(geometry.components[0],style);for(var i=1;i<geometry.components.length;i++){this.drawLinearRing(geometry.components[i],{fillOpacity:0,strokeWidth:0,strokeOpacity:0,strokeColor:'#000000',fillColor:'#000000'});}},drawText:function(location,style){style=OpenLayers.Util.extend({fontColor:"#000000",labelAlign:"cm"},style);var pt=this.getLocalXY(location);this.setCanvasStyle("reset");this.canvas.fillStyle=style.fontColor;this.canvas.globalAlpha=style.fontOpacity||1.0;var fontStyle=style.fontWeight+" "+style.fontSize+" "+style.fontFamily;if(this.canvas.fillText){var labelAlign=OpenLayers.Renderer.Canvas.LABEL_ALIGN[style.labelAlign[0]]||"center";this.canvas.font=fontStyle;this.canvas.textAlign=labelAlign;this.canvas.fillText(style.label,pt[0],pt[1]);}else if(this.canvas.mozDrawText){this.canvas.mozTextStyle=fontStyle;var len=this.canvas.mozMeasureText(style.label);switch(style.labelAlign[0]){case"l":break;case"r":pt[0]-=len;break;case"c":default:pt[0]-=len/2;}
+this.canvas.translate(pt[0],pt[1]);this.canvas.mozDrawText(style.label);this.canvas.translate(-1*pt[0],-1*pt[1]);}
+this.setCanvasStyle("reset");},getLocalXY:function(point){var resolution=this.getResolution();var extent=this.extent;var x=(point.x/resolution+(-extent.left/resolution));var y=((extent.top/resolution)-point.y/resolution);return[x,y];},clear:function(){this.canvas.clearRect(0,0,this.root.width,this.root.height);this.features={};},getFeatureIdFromEvent:function(evt){var loc=this.map.getLonLatFromPixel(evt.xy);var resolution=this.getResolution();var bounds=new OpenLayers.Bounds(loc.lon-resolution*5,loc.lat-resolution*5,loc.lon+resolution*5,loc.lat+resolution*5);var geom=bounds.toGeometry();for(var feat in this.features){if(!this.features.hasOwnProperty(feat)){continue;}
+if(this.features[feat][0].geometry.intersects(geom)){return feat;}}
+return null;},eraseFeatures:function(features){if(!(features instanceof Array)){features=[features];}
+for(var i=0;i<features.length;++i){delete this.features[features[i].id];}
+this.redraw();},redraw:function(){if(!this.locked){this.canvas.clearRect(0,0,this.root.width,this.root.height);var labelMap=[];var feature,style;for(var id in this.features){if(!this.features.hasOwnProperty(id)){continue;}
+feature=this.features[id][0];style=this.features[id][1];if(!feature.geometry){continue;}
+this.drawGeometry(feature.geometry,style);if(style.label){labelMap.push([feature,style]);}}
+var item;for(var i=0,len=labelMap.length;i<len;++i){item=labelMap[i];this.drawText(item[0].geometry.getCentroid(),item[1]);}}},CLASS_NAME:"OpenLayers.Renderer.Canvas"});OpenLayers.Renderer.Canvas.LABEL_ALIGN={"l":"left","r":"right"};OpenLayers.ElementsIndexer=OpenLayers.Class({maxZIndex:null,order:null,indices:null,compare:null,initialize:function(yOrdering){this.compare=yOrdering?OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_Y_ORDER:OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_DRAWING_ORDER;this.order=[];this.indices={};this.maxZIndex=0;},insert:function(newNode){if(this.exists(newNode)){this.remove(newNode);}
+var nodeId=newNode.id;this.determineZIndex(newNode);var leftIndex=-1;var rightIndex=this.order.length;var middle;while(rightIndex-leftIndex>1){middle=parseInt((leftIndex+rightIndex)/2);var placement=this.compare(this,newNode,OpenLayers.Util.getElement(this.order[middle]));if(placement>0){leftIndex=middle;}else{rightIndex=middle;}}
+this.order.splice(rightIndex,0,nodeId);this.indices[nodeId]=this.getZIndex(newNode);return this.getNextElement(rightIndex);},remove:function(node){var nodeId=node.id;var arrayIndex=OpenLayers.Util.indexOf(this.order,nodeId);if(arrayIndex>=0){this.order.splice(arrayIndex,1);delete this.indices[nodeId];if(this.order.length>0){var lastId=this.order[this.order.length-1];this.maxZIndex=this.indices[lastId];}else{this.maxZIndex=0;}}},clear:function(){this.order=[];this.indices={};this.maxZIndex=0;},exists:function(node){return(this.indices[node.id]!=null);},getZIndex:function(node){return node._style.graphicZIndex;},determineZIndex:function(node){var zIndex=node._style.graphicZIndex;if(zIndex==null){zIndex=this.maxZIndex;node._style.graphicZIndex=zIndex;}else if(zIndex>this.maxZIndex){this.maxZIndex=zIndex;}},getNextElement:function(index){var nextIndex=index+1;if(nextIndex<this.order.length){var nextElement=OpenLayers.Util.getElement(this.order[nextIndex]);if(nextElement==undefined){nextElement=this.getNextElement(nextIndex);}
+return nextElement;}else{return null;}},CLASS_NAME:"OpenLayers.ElementsIndexer"});OpenLayers.ElementsIndexer.IndexingMethods={Z_ORDER:function(indexer,newNode,nextNode){var newZIndex=indexer.getZIndex(newNode);var returnVal=0;if(nextNode){var nextZIndex=indexer.getZIndex(nextNode);returnVal=newZIndex-nextZIndex;}
+return returnVal;},Z_ORDER_DRAWING_ORDER:function(indexer,newNode,nextNode){var returnVal=OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(indexer,newNode,nextNode);if(nextNode&&returnVal==0){returnVal=1;}
+return returnVal;},Z_ORDER_Y_ORDER:function(indexer,newNode,nextNode){var returnVal=OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(indexer,newNode,nextNode);if(nextNode&&returnVal===0){var result=nextNode._boundsBottom-newNode._boundsBottom;returnVal=(result===0)?1:result;}
+return returnVal;}};OpenLayers.Renderer.Elements=OpenLayers.Class(OpenLayers.Renderer,{rendererRoot:null,root:null,vectorRoot:null,textRoot:null,xmlns:null,indexer:null,BACKGROUND_ID_SUFFIX:"_background",LABEL_ID_SUFFIX:"_label",initialize:function(containerID,options){OpenLayers.Renderer.prototype.initialize.apply(this,arguments);this.rendererRoot=this.createRenderRoot();this.root=this.createRoot("_root");this.vectorRoot=this.createRoot("_vroot");this.textRoot=this.createRoot("_troot");this.root.appendChild(this.vectorRoot);this.root.appendChild(this.textRoot);this.rendererRoot.appendChild(this.root);this.container.appendChild(this.rendererRoot);if(options&&(options.zIndexing||options.yOrdering)){this.indexer=new OpenLayers.ElementsIndexer(options.yOrdering);}},destroy:function(){this.clear();this.rendererRoot=null;this.root=null;this.xmlns=null;OpenLayers.Renderer.prototype.destroy.apply(this,arguments);},clear:function(){var child;var root=this.vectorRoot;if(root){while(child=root.firstChild){root.removeChild(child);}}
+root=this.textRoot;if(root){while(child=root.firstChild){root.removeChild(child);}}
+if(this.indexer){this.indexer.clear();}},getNodeType:function(geometry,style){},drawGeometry:function(geometry,style,featureId){var className=geometry.CLASS_NAME;var rendered=true;if((className=="OpenLayers.Geometry.Collection")||(className=="OpenLayers.Geometry.MultiPoint")||(className=="OpenLayers.Geometry.MultiLineString")||(className=="OpenLayers.Geometry.MultiPolygon")){for(var i=0,len=geometry.components.length;i<len;i++){rendered=this.drawGeometry(geometry.components[i],style,featureId)&&rendered;}
+return rendered;};rendered=false;if(style.display!="none"){if(style.backgroundGraphic){this.redrawBackgroundNode(geometry.id,geometry,style,featureId);}
+rendered=this.redrawNode(geometry.id,geometry,style,featureId);}
+if(rendered==false){var node=document.getElementById(geometry.id);if(node){if(node._style.backgroundGraphic){node.parentNode.removeChild(document.getElementById(geometry.id+this.BACKGROUND_ID_SUFFIX));}
+node.parentNode.removeChild(node);}}
+return rendered;},redrawNode:function(id,geometry,style,featureId){style=this.applyDefaultSymbolizer(style);var node=this.nodeFactory(id,this.getNodeType(geometry,style));node._featureId=featureId;node._boundsBottom=geometry.getBounds().bottom;node._geometryClass=geometry.CLASS_NAME;node._style=style;var drawResult=this.drawGeometryNode(node,geometry,style);if(drawResult===false){return false;}
+node=drawResult.node;if(this.indexer){var insert=this.indexer.insert(node);if(insert){this.vectorRoot.insertBefore(node,insert);}else{this.vectorRoot.appendChild(node);}}else{if(node.parentNode!==this.vectorRoot){this.vectorRoot.appendChild(node);}}
+this.postDraw(node);return drawResult.complete;},redrawBackgroundNode:function(id,geometry,style,featureId){var backgroundStyle=OpenLayers.Util.extend({},style);backgroundStyle.externalGraphic=backgroundStyle.backgroundGraphic;backgroundStyle.graphicXOffset=backgroundStyle.backgroundXOffset;backgroundStyle.graphicYOffset=backgroundStyle.backgroundYOffset;backgroundStyle.graphicZIndex=backgroundStyle.backgroundGraphicZIndex;backgroundStyle.graphicWidth=backgroundStyle.backgroundWidth||backgroundStyle.graphicWidth;backgroundStyle.graphicHeight=backgroundStyle.backgroundHeight||backgroundStyle.graphicHeight;backgroundStyle.backgroundGraphic=null;backgroundStyle.backgroundXOffset=null;backgroundStyle.backgroundYOffset=null;backgroundStyle.backgroundGraphicZIndex=null;return this.redrawNode(id+this.BACKGROUND_ID_SUFFIX,geometry,backgroundStyle,null);},drawGeometryNode:function(node,geometry,style){style=style||node._style;var options={'isFilled':style.fill===undefined?true:style.fill,'isStroked':style.stroke===undefined?!!style.strokeWidth:style.stroke};var drawn;switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":if(style.graphic===false){options.isFilled=false;options.isStroked=false;}
+drawn=this.drawPoint(node,geometry);break;case"OpenLayers.Geometry.LineString":options.isFilled=false;drawn=this.drawLineString(node,geometry);break;case"OpenLayers.Geometry.LinearRing":drawn=this.drawLinearRing(node,geometry);break;case"OpenLayers.Geometry.Polygon":drawn=this.drawPolygon(node,geometry);break;case"OpenLayers.Geometry.Surface":drawn=this.drawSurface(node,geometry);break;case"OpenLayers.Geometry.Rectangle":drawn=this.drawRectangle(node,geometry);break;default:break;}
+node._options=options;if(drawn!=false){return{node:this.setStyle(node,style,options,geometry),complete:drawn};}else{return false;}},postDraw:function(node){},drawPoint:function(node,geometry){},drawLineString:function(node,geometry){},drawLinearRing:function(node,geometry){},drawPolygon:function(node,geometry){},drawRectangle:function(node,geometry){},drawCircle:function(node,geometry){},drawSurface:function(node,geometry){},removeText:function(featureId){var label=document.getElementById(featureId+this.LABEL_ID_SUFFIX);if(label){this.textRoot.removeChild(label);}},getFeatureIdFromEvent:function(evt){var target=evt.target;var useElement=target&&target.correspondingUseElement;var node=useElement?useElement:(target||evt.srcElement);var featureId=node._featureId;return featureId;},eraseGeometry:function(geometry,featureId){if((geometry.CLASS_NAME=="OpenLayers.Geometry.MultiPoint")||(geometry.CLASS_NAME=="OpenLayers.Geometry.MultiLineString")||(geometry.CLASS_NAME=="OpenLayers.Geometry.MultiPolygon")||(geometry.CLASS_NAME=="OpenLayers.Geometry.Collection")){for(var i=0,len=geometry.components.length;i<len;i++){this.eraseGeometry(geometry.components[i],featureId);}}else{var element=OpenLayers.Util.getElement(geometry.id);if(element&&element.parentNode){if(element.geometry){element.geometry.destroy();element.geometry=null;}
+element.parentNode.removeChild(element);if(this.indexer){this.indexer.remove(element);}
+if(element._style.backgroundGraphic){var backgroundId=geometry.id+this.BACKGROUND_ID_SUFFIX;var bElem=OpenLayers.Util.getElement(backgroundId);if(bElem&&bElem.parentNode){bElem.parentNode.removeChild(bElem);}}}}},nodeFactory:function(id,type){var node=OpenLayers.Util.getElement(id);if(node){if(!this.nodeTypeCompare(node,type)){node.parentNode.removeChild(node);node=this.nodeFactory(id,type);}}else{node=this.createNode(type,id);}
+return node;},nodeTypeCompare:function(node,type){},createNode:function(type,id){},moveRoot:function(renderer){var root=this.root;if(renderer.root.parentNode==this.rendererRoot){root=renderer.root;}
+root.parentNode.removeChild(root);renderer.rendererRoot.appendChild(root);},getRenderLayerId:function(){return this.root.parentNode.parentNode.id;},isComplexSymbol:function(graphicName){return(graphicName!="circle")&&!!graphicName;},CLASS_NAME:"OpenLayers.Renderer.Elements"});OpenLayers.Renderer.symbol={"star":[350,75,379,161,469,161,397,215,423,301,350,250,277,301,303,215,231,161,321,161,350,75],"cross":[4,0,6,0,6,4,10,4,10,6,6,6,6,10,4,10,4,6,0,6,0,4,4,4,4,0],"x":[0,0,25,0,50,35,75,0,100,0,65,50,100,100,75,100,50,65,25,100,0,100,35,50,0,0],"square":[0,0,0,1,1,1,1,0,0,0],"triangle":[0,10,10,10,5,0,0,10]};OpenLayers.Strategy.Cluster=OpenLayers.Class(OpenLayers.Strategy,{distance:20,threshold:null,features:null,clusters:null,clustering:false,resolution:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){this.layer.events.on({"beforefeaturesadded":this.cacheFeatures,"moveend":this.cluster,scope:this});}
+return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.clearCache();this.layer.events.un({"beforefeaturesadded":this.cacheFeatures,"moveend":this.cluster,scope:this});}
+return deactivated;},cacheFeatures:function(event){var propagate=true;if(!this.clustering){this.clearCache();this.features=event.features;this.cluster();propagate=false;}
+return propagate;},clearCache:function(){this.features=null;},cluster:function(event){if((!event||event.zoomChanged)&&this.features){var resolution=this.layer.map.getResolution();if(resolution!=this.resolution||!this.clustersExist()){this.resolution=resolution;var clusters=[];var feature,clustered,cluster;for(var i=0;i<this.features.length;++i){feature=this.features[i];if(feature.geometry){clustered=false;for(var j=clusters.length-1;j>=0;--j){cluster=clusters[j];if(this.shouldCluster(cluster,feature)){this.addToCluster(cluster,feature);clustered=true;break;}}
+if(!clustered){clusters.push(this.createCluster(this.features[i]));}}}
+this.layer.removeAllFeatures();if(clusters.length>0){if(this.threshold>1){var clone=clusters.slice();clusters=[];var candidate;for(var i=0,len=clone.length;i<len;++i){candidate=clone[i];if(candidate.attributes.count<this.threshold){Array.prototype.push.apply(clusters,candidate.cluster);}else{clusters.push(candidate);}}}
+this.clustering=true;this.layer.addFeatures(clusters);this.clustering=false;}
+this.clusters=clusters;}}},clustersExist:function(){var exist=false;if(this.clusters&&this.clusters.length>0&&this.clusters.length==this.layer.features.length){exist=true;for(var i=0;i<this.clusters.length;++i){if(this.clusters[i]!=this.layer.features[i]){exist=false;break;}}}
+return exist;},shouldCluster:function(cluster,feature){var cc=cluster.geometry.getBounds().getCenterLonLat();var fc=feature.geometry.getBounds().getCenterLonLat();var distance=(Math.sqrt(Math.pow((cc.lon-fc.lon),2)+Math.pow((cc.lat-fc.lat),2))/this.resolution);return(distance<=this.distance);},addToCluster:function(cluster,feature){cluster.cluster.push(feature);cluster.attributes.count+=1;},createCluster:function(feature){var center=feature.geometry.getBounds().getCenterLonLat();var cluster=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(center.lon,center.lat),{count:1});cluster.cluster=[feature];return cluster;},CLASS_NAME:"OpenLayers.Strategy.Cluster"});OpenLayers.Strategy.Fixed=OpenLayers.Class(OpenLayers.Strategy,{preload:false,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},destroy:function(){OpenLayers.Strategy.prototype.destroy.apply(this,arguments);},activate:function(){if(OpenLayers.Strategy.prototype.activate.apply(this,arguments)){this.layer.events.on({"refresh":this.load,scope:this});if(this.layer.visibility==true||this.preload){this.load();}else{this.layer.events.on({"visibilitychanged":this.load,scope:this});}
+return true;}
+return false;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.layer.events.un({"refresh":this.load,"visibilitychanged":this.load,scope:this});}
+return deactivated;},load:function(options){this.layer.events.triggerEvent("loadstart");this.layer.protocol.read(OpenLayers.Util.applyDefaults({callback:this.merge,filter:this.layer.filter,scope:this},options));this.layer.events.un({"visibilitychanged":this.load,scope:this});},merge:function(resp){this.layer.destroyFeatures();var features=resp.features;if(features&&features.length>0){var remote=this.layer.projection;var local=this.layer.map.getProjectionObject();if(!local.equals(remote)){var geom;for(var i=0,len=features.length;i<len;++i){geom=features[i].geometry;if(geom){geom.transform(remote,local);}}}
+this.layer.addFeatures(features);}
+this.layer.events.triggerEvent("loadend");},CLASS_NAME:"OpenLayers.Strategy.Fixed"});OpenLayers.Strategy.Paging=OpenLayers.Class(OpenLayers.Strategy,{features:null,length:10,num:null,paging:false,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){this.layer.events.on({"beforefeaturesadded":this.cacheFeatures,scope:this});}
+return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.clearCache();this.layer.events.un({"beforefeaturesadded":this.cacheFeatures,scope:this});}
+return deactivated;},cacheFeatures:function(event){if(!this.paging){this.clearCache();this.features=event.features;this.pageNext(event);}},clearCache:function(){if(this.features){for(var i=0;i<this.features.length;++i){this.features[i].destroy();}}
+this.features=null;this.num=null;},pageCount:function(){var numFeatures=this.features?this.features.length:0;return Math.ceil(numFeatures/this.length);},pageNum:function(){return this.num;},pageLength:function(newLength){if(newLength&&newLength>0){this.length=newLength;}
+return this.length;},pageNext:function(event){var changed=false;if(this.features){if(this.num===null){this.num=-1;}
+var start=(this.num+1)*this.length;changed=this.page(start,event);}
+return changed;},pagePrevious:function(){var changed=false;if(this.features){if(this.num===null){this.num=this.pageCount();}
+var start=(this.num-1)*this.length;changed=this.page(start);}
+return changed;},page:function(start,event){var changed=false;if(this.features){if(start>=0&&start<this.features.length){var num=Math.floor(start/this.length);if(num!=this.num){this.paging=true;var features=this.features.slice(start,start+this.length);this.layer.removeFeatures(this.layer.features);this.num=num;if(event&&event.features){event.features=features;}else{this.layer.addFeatures(features);}
+this.paging=false;changed=true;}}}
+return changed;},CLASS_NAME:"OpenLayers.Strategy.Paging"});OpenLayers.Strategy.Refresh=OpenLayers.Class(OpenLayers.Strategy,{force:false,interval:0,timer:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){if(this.layer.visibility===true){this.start();}
+this.layer.events.on({"visibilitychanged":this.reset,scope:this});}
+return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.stop();}
+return deactivated;},reset:function(){if(this.layer.visibility===true){this.start();}else{this.stop();}},start:function(){if(this.interval&&typeof this.interval==="number"&&this.interval>0){this.timer=window.setInterval(OpenLayers.Function.bind(this.refresh,this),this.interval);}},refresh:function(){if(this.layer&&this.layer.refresh&&typeof this.layer.refresh=="function"){this.layer.refresh({force:this.force});}},stop:function(){if(this.timer!==null){window.clearInterval(this.timer);this.timer=null;}},CLASS_NAME:"OpenLayers.Strategy.Refresh"});OpenLayers.Strategy.Save=OpenLayers.Class(OpenLayers.Strategy,{EVENT_TYPES:["start","success","fail"],events:null,auto:false,timer:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){if(this.auto){if(typeof this.auto==="number"){this.timer=window.setInterval(OpenLayers.Function.bind(this.save,this),this.auto*1000);}else{this.layer.events.on({"featureadded":this.triggerSave,"afterfeaturemodified":this.triggerSave,scope:this});}}}
+return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){if(this.auto){if(typeof this.auto==="number"){window.clearInterval(this.timer);}else{this.layer.events.un({"featureadded":this.triggerSave,"afterfeaturemodified":this.triggerSave,scope:this});}}}
+return deactivated;},triggerSave:function(event){var feature=event.feature;if(feature.state===OpenLayers.State.INSERT||feature.state===OpenLayers.State.UPDATE||feature.state===OpenLayers.State.DELETE){this.save([event.feature]);}},save:function(features){if(!features){features=this.layer.features;}
+this.events.triggerEvent("start",{features:features});var remote=this.layer.projection;var local=this.layer.map.getProjectionObject();if(!local.equals(remote)){var len=features.length;var clones=new Array(len);var orig,clone;for(var i=0;i<len;++i){orig=features[i];clone=orig.clone();clone.fid=orig.fid;clone.state=orig.state;if(orig.url){clone.url=orig.url;}
+clone._original=orig;clone.geometry.transform(local,remote);clones[i]=clone;}
+features=clones;}
+this.layer.protocol.commit(features,{callback:this.onCommit,scope:this});},onCommit:function(response){var evt={"response":response};if(response.success()){var features=response.reqFeatures;var state,feature;var destroys=[];var insertIds=response.insertIds||[];var j=0;for(var i=0,len=features.length;i<len;++i){feature=features[i];feature=feature._original||feature;state=feature.state;if(state){if(state==OpenLayers.State.DELETE){destroys.push(feature);}else if(state==OpenLayers.State.INSERT){feature.fid=insertIds[j];++j;}
+feature.state=null;}}
+if(destroys.length>0){this.layer.destroyFeatures(destroys);}
+this.events.triggerEvent("success",evt);}else{this.events.triggerEvent("fail",evt);}},CLASS_NAME:"OpenLayers.Strategy.Save"});OpenLayers.Symbolizer.Line=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Line"});OpenLayers.Symbolizer.Point=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,fillColor:null,fillOpacity:null,pointRadius:null,externalGraphic:null,graphicWidth:null,graphicHeight:null,graphicOpacity:null,graphicXOffset:null,graphicYOffset:null,rotation:null,graphicName:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Point"});OpenLayers.Symbolizer.Polygon=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,fillColor:null,fillOpacity:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Polygon"});OpenLayers.Symbolizer.Raster=OpenLayers.Class(OpenLayers.Symbolizer,{initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Raster"});OpenLayers.Symbolizer.Text=OpenLayers.Class(OpenLayers.Symbolizer,{label:null,fontFamily:null,fontSize:null,fontWeight:null,fontStyle:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Text"});OpenLayers.Tween=OpenLayers.Class({INTERVAL:10,easing:null,begin:null,finish:null,duration:null,callbacks:null,time:null,interval:null,playing:false,initialize:function(easing){this.easing=(easing)?easing:OpenLayers.Easing.Expo.easeOut;},start:function(begin,finish,duration,options){this.playing=true;this.begin=begin;this.finish=finish;this.duration=duration;this.callbacks=options.callbacks;this.time=0;if(this.interval){window.clearInterval(this.interval);this.interval=null;}
+if(this.callbacks&&this.callbacks.start){this.callbacks.start.call(this,this.begin);}
+this.interval=window.setInterval(OpenLayers.Function.bind(this.play,this),this.INTERVAL);},stop:function(){if(!this.playing){return;}
+if(this.callbacks&&this.callbacks.done){this.callbacks.done.call(this,this.finish);}
+window.clearInterval(this.interval);this.interval=null;this.playing=false;},play:function(){var value={};for(var i in this.begin){var b=this.begin[i];var f=this.finish[i];if(b==null||f==null||isNaN(b)||isNaN(f)){OpenLayers.Console.error('invalid value for Tween');}
+var c=f-b;value[i]=this.easing.apply(this,[this.time,b,c,this.duration]);}
+this.time++;if(this.callbacks&&this.callbacks.eachStep){this.callbacks.eachStep.call(this,value);}
+if(this.time>this.duration){this.stop();}},CLASS_NAME:"OpenLayers.Tween"});OpenLayers.Easing={CLASS_NAME:"OpenLayers.Easing"};OpenLayers.Easing.Linear={easeIn:function(t,b,c,d){return c*t/d+b;},easeOut:function(t,b,c,d){return c*t/d+b;},easeInOut:function(t,b,c,d){return c*t/d+b;},CLASS_NAME:"OpenLayers.Easing.Linear"};OpenLayers.Easing.Expo={easeIn:function(t,b,c,d){return(t==0)?b:c*Math.pow(2,10*(t/d-1))+b;},easeOut:function(t,b,c,d){return(t==d)?b+c:c*(-Math.pow(2,-10*t/d)+1)+b;},easeInOut:function(t,b,c,d){if(t==0)return b;if(t==d)return b+c;if((t/=d/2)<1)return c/2*Math.pow(2,10*(t-1))+b;return c/2*(-Math.pow(2,-10*--t)+2)+b;},CLASS_NAME:"OpenLayers.Easing.Expo"};OpenLayers.Easing.Quad={easeIn:function(t,b,c,d){return c*(t/=d)*t+b;},easeOut:function(t,b,c,d){return-c*(t/=d)*(t-2)+b;},easeInOut:function(t,b,c,d){if((t/=d/2)<1)return c/2*t*t+b;return-c/2*((--t)*(t-2)-1)+b;},CLASS_NAME:"OpenLayers.Easing.Quad"};OpenLayers.Control.ArgParser=OpenLayers.Class(OpenLayers.Control,{center:null,zoom:null,layers:null,displayProjection:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);},setMap:function(map){OpenLayers.Control.prototype.setMap.apply(this,arguments);for(var i=0,len=this.map.controls.length;i<len;i++){var control=this.map.controls[i];if((control!=this)&&(control.CLASS_NAME=="OpenLayers.Control.ArgParser")){if(control.displayProjection!=this.displayProjection){this.displayProjection=control.displayProjection;}
+break;}}
+if(i==this.map.controls.length){var args=OpenLayers.Util.getParameters();if(args.layers){this.layers=args.layers;this.map.events.register('addlayer',this,this.configureLayers);this.configureLayers();}
+if(args.lat&&args.lon){this.center=new OpenLayers.LonLat(parseFloat(args.lon),parseFloat(args.lat));if(args.zoom){this.zoom=parseInt(args.zoom);}
+this.map.events.register('changebaselayer',this,this.setCenter);this.setCenter();}}},setCenter:function(){if(this.map.baseLayer){this.map.events.unregister('changebaselayer',this,this.setCenter);if(this.displayProjection){this.center.transform(this.displayProjection,this.map.getProjectionObject());}
+this.map.setCenter(this.center,this.zoom);}},configureLayers:function(){if(this.layers.length==this.map.layers.length){this.map.events.unregister('addlayer',this,this.configureLayers);for(var i=0,len=this.layers.length;i<len;i++){var layer=this.map.layers[i];var c=this.layers.charAt(i);if(c=="B"){this.map.setBaseLayer(layer);}else if((c=="T")||(c=="F")){layer.setVisibility(c=="T");}}}},CLASS_NAME:"OpenLayers.Control.ArgParser"});OpenLayers.Control.Attribution=OpenLayers.Class(OpenLayers.Control,{separator:", ",initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){this.map.events.un({"removelayer":this.updateAttribution,"addlayer":this.updateAttribution,"changelayer":this.updateAttribution,"changebaselayer":this.updateAttribution,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.map.events.on({'changebaselayer':this.updateAttribution,'changelayer':this.updateAttribution,'addlayer':this.updateAttribution,'removelayer':this.updateAttribution,scope:this});this.updateAttribution();return this.div;},updateAttribution:function(){var attributions=[];if(this.map&&this.map.layers){for(var i=0,len=this.map.layers.length;i<len;i++){var layer=this.map.layers[i];if(layer.attribution&&layer.getVisibility()){if(OpenLayers.Util.indexOf(attributions,layer.attribution)===-1){attributions.push(layer.attribution);}}}
+this.div.innerHTML=attributions.join(this.separator);}},CLASS_NAME:"OpenLayers.Control.Attribution"});OpenLayers.Control.Button=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){},CLASS_NAME:"OpenLayers.Control.Button"});OpenLayers.Control.Graticule=OpenLayers.Class(OpenLayers.Control,{autoActivate:true,intervals:[45,30,20,10,5,2,1,0.5,0.2,0.1,0.05,0.01,0.005,0.002,0.001],displayInLayerSwitcher:true,visible:true,numPoints:50,targetSize:200,layerName:null,labelled:true,labelFormat:'dm',lineSymbolizer:{strokeColor:"#333",strokeWidth:1,strokeOpacity:0.5},labelSymbolizer:{},gratLayer:null,initialize:function(options){options=options||{};options.layerName=options.layerName||OpenLayers.i18n("graticule");OpenLayers.Control.prototype.initialize.apply(this,[options]);this.labelSymbolizer.stroke=false;this.labelSymbolizer.fill=false;this.labelSymbolizer.label="${label}";this.labelSymbolizer.labelAlign="${labelAlign}";this.labelSymbolizer.labelXOffset="${xOffset}";this.labelSymbolizer.labelYOffset="${yOffset}";},destroy:function(){this.deactivate();OpenLayers.Control.prototype.destroy.apply(this,arguments);if(this.gratLayer){this.gratLayer.destroy();this.gratLayer=null;}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.gratLayer){var gratStyle=new OpenLayers.Style({},{rules:[new OpenLayers.Rule({'symbolizer':{"Point":this.labelSymbolizer,"Line":this.lineSymbolizer}})]});this.gratLayer=new OpenLayers.Layer.Vector(this.layerName,{styleMap:new OpenLayers.StyleMap({'default':gratStyle}),visibility:this.visible,displayInLayerSwitcher:this.displayInLayerSwitcher});}
+return this.div;},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){this.map.addLayer(this.gratLayer);this.map.events.register('moveend',this,this.update);this.update();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.map.events.unregister('moveend',this,this.update);this.map.removeLayer(this.gratLayer);return true;}else{return false;}},update:function(){var mapBounds=this.map.getExtent();if(!mapBounds){return;}
+this.gratLayer.destroyFeatures();var llProj=new OpenLayers.Projection("EPSG:4326");var mapProj=this.map.getProjectionObject();var mapRes=this.map.getResolution();if(mapProj.proj&&mapProj.proj.projName=="longlat"){this.numPoints=1;}
+var mapCenter=this.map.getCenter();var mapCenterLL=new OpenLayers.Pixel(mapCenter.lon,mapCenter.lat);OpenLayers.Projection.transform(mapCenterLL,mapProj,llProj);var testSq=this.targetSize*mapRes;testSq*=testSq;var llInterval;for(var i=0;i<this.intervals.length;++i){llInterval=this.intervals[i];var delta=llInterval/2;var p1=mapCenterLL.offset(new OpenLayers.Pixel(-delta,-delta));var p2=mapCenterLL.offset(new OpenLayers.Pixel(delta,delta));OpenLayers.Projection.transform(p1,llProj,mapProj);OpenLayers.Projection.transform(p2,llProj,mapProj);var distSq=(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);if(distSq<=testSq){break;}}
+mapCenterLL.x=Math.floor(mapCenterLL.x/llInterval)*llInterval;mapCenterLL.y=Math.floor(mapCenterLL.y/llInterval)*llInterval;var iter=0;var centerLonPoints=[mapCenterLL.clone()];var newPoint=mapCenterLL.clone();var mapXY;do{newPoint=newPoint.offset(new OpenLayers.Pixel(0,llInterval));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLonPoints.unshift(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);newPoint=mapCenterLL.clone();do{newPoint=newPoint.offset(new OpenLayers.Pixel(0,-llInterval));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLonPoints.push(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);iter=0;var centerLatPoints=[mapCenterLL.clone()];newPoint=mapCenterLL.clone();do{newPoint=newPoint.offset(new OpenLayers.Pixel(-llInterval,0));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLatPoints.unshift(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);newPoint=mapCenterLL.clone();do{newPoint=newPoint.offset(new OpenLayers.Pixel(llInterval,0));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLatPoints.push(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);var lines=[];for(var i=0;i<centerLatPoints.length;++i){var lon=centerLatPoints[i].x;var pointList=[];var labelPoint=null;var latEnd=Math.min(centerLonPoints[0].y,90);var latStart=Math.max(centerLonPoints[centerLonPoints.length-1].y,-90);var latDelta=(latEnd-latStart)/this.numPoints;var lat=latStart;for(var j=0;j<=this.numPoints;++j){var gridPoint=new OpenLayers.Geometry.Point(lon,lat);gridPoint.transform(llProj,mapProj);pointList.push(gridPoint);lat+=latDelta;if(gridPoint.y>=mapBounds.bottom&&!labelPoint){labelPoint=gridPoint;}}
+if(this.labelled){var labelPos=new OpenLayers.Geometry.Point(labelPoint.x,mapBounds.bottom);var labelAttrs={value:lon,label:this.labelled?OpenLayers.Util.getFormattedLonLat(lon,"lon",this.labelFormat):"",labelAlign:"cb",xOffset:0,yOffset:2};this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(labelPos,labelAttrs));}
+var geom=new OpenLayers.Geometry.LineString(pointList);lines.push(new OpenLayers.Feature.Vector(geom));}
+for(var j=0;j<centerLonPoints.length;++j){lat=centerLonPoints[j].y;if(lat<-90||lat>90){continue;}
+var pointList=[];var lonStart=centerLatPoints[0].x;var lonEnd=centerLatPoints[centerLatPoints.length-1].x;var lonDelta=(lonEnd-lonStart)/this.numPoints;var lon=lonStart;var labelPoint=null;for(var i=0;i<=this.numPoints;++i){var gridPoint=new OpenLayers.Geometry.Point(lon,lat);gridPoint.transform(llProj,mapProj);pointList.push(gridPoint);lon+=lonDelta;if(gridPoint.x<mapBounds.right){labelPoint=gridPoint;}}
+if(this.labelled){var labelPos=new OpenLayers.Geometry.Point(mapBounds.right,labelPoint.y);var labelAttrs={value:lat,label:this.labelled?OpenLayers.Util.getFormattedLonLat(lat,"lat",this.labelFormat):"",labelAlign:"rb",xOffset:-2,yOffset:2};this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(labelPos,labelAttrs));}
+var geom=new OpenLayers.Geometry.LineString(pointList);lines.push(new OpenLayers.Feature.Vector(geom));}
+this.gratLayer.addFeatures(lines);},CLASS_NAME:"OpenLayers.Control.Graticule"});OpenLayers.Control.LayerSwitcher=OpenLayers.Class(OpenLayers.Control,{roundedCorner:true,roundedCornerColor:"darkblue",layerStates:null,layersDiv:null,baseLayersDiv:null,baseLayers:null,dataLbl:null,dataLayersDiv:null,dataLayers:null,minimizeDiv:null,maximizeDiv:null,ascending:true,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);this.layerStates=[];},destroy:function(){OpenLayers.Event.stopObservingElement(this.div);OpenLayers.Event.stopObservingElement(this.minimizeDiv);OpenLayers.Event.stopObservingElement(this.maximizeDiv);this.clearLayersArray("base");this.clearLayersArray("data");this.map.events.un({"addlayer":this.redraw,"changelayer":this.redraw,"removelayer":this.redraw,"changebaselayer":this.redraw,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Control.prototype.setMap.apply(this,arguments);this.map.events.on({"addlayer":this.redraw,"changelayer":this.redraw,"removelayer":this.redraw,"changebaselayer":this.redraw,scope:this});},draw:function(){OpenLayers.Control.prototype.draw.apply(this);this.loadContents();if(!this.outsideViewport){this.minimizeControl();}
+this.redraw();return this.div;},clearLayersArray:function(layersType){var layers=this[layersType+"Layers"];if(layers){for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];OpenLayers.Event.stopObservingElement(layer.inputElem);OpenLayers.Event.stopObservingElement(layer.labelSpan);}}
+this[layersType+"LayersDiv"].innerHTML="";this[layersType+"Layers"]=[];},checkRedraw:function(){var redraw=false;if(!this.layerStates.length||(this.map.layers.length!=this.layerStates.length)){redraw=true;}else{for(var i=0,len=this.layerStates.length;i<len;i++){var layerState=this.layerStates[i];var layer=this.map.layers[i];if((layerState.name!=layer.name)||(layerState.inRange!=layer.inRange)||(layerState.id!=layer.id)||(layerState.visibility!=layer.visibility)){redraw=true;break;}}}
+return redraw;},redraw:function(){if(!this.checkRedraw()){return this.div;}
+this.clearLayersArray("base");this.clearLayersArray("data");var containsOverlays=false;var containsBaseLayers=false;var len=this.map.layers.length;this.layerStates=new Array(len);for(var i=0;i<len;i++){var layer=this.map.layers[i];this.layerStates[i]={'name':layer.name,'visibility':layer.visibility,'inRange':layer.inRange,'id':layer.id};}
+var layers=this.map.layers.slice();if(!this.ascending){layers.reverse();}
+for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];var baseLayer=layer.isBaseLayer;if(layer.displayInLayerSwitcher){if(baseLayer){containsBaseLayers=true;}else{containsOverlays=true;}
+var checked=(baseLayer)?(layer==this.map.baseLayer):layer.getVisibility();var inputElem=document.createElement("input");inputElem.id=this.id+"_input_"+layer.name;inputElem.name=(baseLayer)?this.id+"_baseLayers":layer.name;inputElem.type=(baseLayer)?"radio":"checkbox";inputElem.value=layer.name;inputElem.checked=checked;inputElem.defaultChecked=checked;if(!baseLayer&&!layer.inRange){inputElem.disabled=true;}
+var context={'inputElem':inputElem,'layer':layer,'layerSwitcher':this};OpenLayers.Event.observe(inputElem,"mouseup",OpenLayers.Function.bindAsEventListener(this.onInputClick,context));var labelSpan=document.createElement("span");OpenLayers.Element.addClass(labelSpan,"labelSpan")
+if(!baseLayer&&!layer.inRange){labelSpan.style.color="gray";}
+labelSpan.innerHTML=layer.name;labelSpan.style.verticalAlign=(baseLayer)?"bottom":"baseline";OpenLayers.Event.observe(labelSpan,"click",OpenLayers.Function.bindAsEventListener(this.onInputClick,context));var br=document.createElement("br");var groupArray=(baseLayer)?this.baseLayers:this.dataLayers;groupArray.push({'layer':layer,'inputElem':inputElem,'labelSpan':labelSpan});var groupDiv=(baseLayer)?this.baseLayersDiv:this.dataLayersDiv;groupDiv.appendChild(inputElem);groupDiv.appendChild(labelSpan);groupDiv.appendChild(br);}}
+this.dataLbl.style.display=(containsOverlays)?"":"none";this.baseLbl.style.display=(containsBaseLayers)?"":"none";return this.div;},onInputClick:function(e){if(!this.inputElem.disabled){if(this.inputElem.type=="radio"){this.inputElem.checked=true;this.layer.map.setBaseLayer(this.layer);}else{this.inputElem.checked=!this.inputElem.checked;this.layerSwitcher.updateMap();}}
+OpenLayers.Event.stop(e);},onLayerClick:function(e){this.updateMap();},updateMap:function(){for(var i=0,len=this.baseLayers.length;i<len;i++){var layerEntry=this.baseLayers[i];if(layerEntry.inputElem.checked){this.map.setBaseLayer(layerEntry.layer,false);}}
+for(var i=0,len=this.dataLayers.length;i<len;i++){var layerEntry=this.dataLayers[i];layerEntry.layer.setVisibility(layerEntry.inputElem.checked);}},maximizeControl:function(e){this.div.style.width="";this.div.style.height="";this.showControls(false);if(e!=null){OpenLayers.Event.stop(e);}},minimizeControl:function(e){this.div.style.width="0px";this.div.style.height="0px";this.showControls(true);if(e!=null){OpenLayers.Event.stop(e);}},showControls:function(minimize){this.maximizeDiv.style.display=minimize?"":"none";this.minimizeDiv.style.display=minimize?"none":"";this.layersDiv.style.display=minimize?"none":"";},loadContents:function(){OpenLayers.Event.observe(this.div,"mouseup",OpenLayers.Function.bindAsEventListener(this.mouseUp,this));OpenLayers.Event.observe(this.div,"click",this.ignoreEvent);OpenLayers.Event.observe(this.div,"mousedown",OpenLayers.Function.bindAsEventListener(this.mouseDown,this));OpenLayers.Event.observe(this.div,"dblclick",this.ignoreEvent);this.layersDiv=document.createElement("div");this.layersDiv.id=this.id+"_layersDiv";OpenLayers.Element.addClass(this.layersDiv,"layersDiv");this.baseLbl=document.createElement("div");this.baseLbl.innerHTML=OpenLayers.i18n("baseLayer");OpenLayers.Element.addClass(this.baseLbl,"baseLbl");this.baseLayersDiv=document.createElement("div");OpenLayers.Element.addClass(this.baseLayersDiv,"baseLayersDiv");this.dataLbl=document.createElement("div");this.dataLbl.innerHTML=OpenLayers.i18n("overlays");OpenLayers.Element.addClass(this.dataLbl,"dataLbl");this.dataLayersDiv=document.createElement("div");OpenLayers.Element.addClass(this.dataLayersDiv,"dataLayersDiv");if(this.ascending){this.layersDiv.appendChild(this.baseLbl);this.layersDiv.appendChild(this.baseLayersDiv);this.layersDiv.appendChild(this.dataLbl);this.layersDiv.appendChild(this.dataLayersDiv);}else{this.layersDiv.appendChild(this.dataLbl);this.layersDiv.appendChild(this.dataLayersDiv);this.layersDiv.appendChild(this.baseLbl);this.layersDiv.appendChild(this.baseLayersDiv);}
+this.div.appendChild(this.layersDiv);if(this.roundedCorner){OpenLayers.Rico.Corner.round(this.div,{corners:"tl bl",bgColor:"transparent",color:this.roundedCornerColor,blend:false});OpenLayers.Rico.Corner.changeOpacity(this.layersDiv,0.75);}
+var imgLocation=OpenLayers.Util.getImagesLocation();var sz=new OpenLayers.Size(18,18);var img=imgLocation+'layer-switcher-maximize.png';this.maximizeDiv=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MaximizeDiv",null,sz,img,"absolute");OpenLayers.Element.addClass(this.maximizeDiv,"maximizeDiv");this.maximizeDiv.style.display="none";OpenLayers.Event.observe(this.maximizeDiv,"click",OpenLayers.Function.bindAsEventListener(this.maximizeControl,this));this.div.appendChild(this.maximizeDiv);var img=imgLocation+'layer-switcher-minimize.png';var sz=new OpenLayers.Size(18,18);this.minimizeDiv=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MinimizeDiv",null,sz,img,"absolute");OpenLayers.Element.addClass(this.minimizeDiv,"minimizeDiv");this.minimizeDiv.style.display="none";OpenLayers.Event.observe(this.minimizeDiv,"click",OpenLayers.Function.bindAsEventListener(this.minimizeControl,this));this.div.appendChild(this.minimizeDiv);},ignoreEvent:function(evt){OpenLayers.Event.stop(evt);},mouseDown:function(evt){this.isMouseDown=true;this.ignoreEvent(evt);},mouseUp:function(evt){if(this.isMouseDown){this.isMouseDown=false;this.ignoreEvent(evt);}},CLASS_NAME:"OpenLayers.Control.LayerSwitcher"});OpenLayers.Control.MouseDefaults=OpenLayers.Class(OpenLayers.Control,{performedDrag:false,wheelObserver:null,initialize:function(){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){if(this.handler){this.handler.destroy();}
+this.handler=null;this.map.events.un({"click":this.defaultClick,"dblclick":this.defaultDblClick,"mousedown":this.defaultMouseDown,"mouseup":this.defaultMouseUp,"mousemove":this.defaultMouseMove,"mouseout":this.defaultMouseOut,scope:this});OpenLayers.Event.stopObserving(window,"DOMMouseScroll",this.wheelObserver);OpenLayers.Event.stopObserving(window,"mousewheel",this.wheelObserver);OpenLayers.Event.stopObserving(document,"mousewheel",this.wheelObserver);this.wheelObserver=null;OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){this.map.events.on({"click":this.defaultClick,"dblclick":this.defaultDblClick,"mousedown":this.defaultMouseDown,"mouseup":this.defaultMouseUp,"mousemove":this.defaultMouseMove,"mouseout":this.defaultMouseOut,scope:this});this.registerWheelEvents();},registerWheelEvents:function(){this.wheelObserver=OpenLayers.Function.bindAsEventListener(this.onWheelEvent,this);OpenLayers.Event.observe(window,"DOMMouseScroll",this.wheelObserver);OpenLayers.Event.observe(window,"mousewheel",this.wheelObserver);OpenLayers.Event.observe(document,"mousewheel",this.wheelObserver);},defaultClick:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
+var notAfterDrag=!this.performedDrag;this.performedDrag=false;return notAfterDrag;},defaultDblClick:function(evt){var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom+1);OpenLayers.Event.stop(evt);return false;},defaultMouseDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
+this.mouseDragStart=evt.xy.clone();this.performedDrag=false;if(evt.shiftKey){this.map.div.style.cursor="crosshair";this.zoomBox=OpenLayers.Util.createDiv('zoomBox',this.mouseDragStart,null,null,"absolute","2px solid red");this.zoomBox.style.backgroundColor="white";this.zoomBox.style.filter="alpha(opacity=50)";this.zoomBox.style.opacity="0.50";this.zoomBox.style.fontSize="1px";this.zoomBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.viewPortDiv.appendChild(this.zoomBox);}
+document.onselectstart=OpenLayers.Function.False;OpenLayers.Event.stop(evt);},defaultMouseMove:function(evt){this.mousePosition=evt.xy.clone();if(this.mouseDragStart!=null){if(this.zoomBox){var deltaX=Math.abs(this.mouseDragStart.x-evt.xy.x);var deltaY=Math.abs(this.mouseDragStart.y-evt.xy.y);this.zoomBox.style.width=Math.max(1,deltaX)+"px";this.zoomBox.style.height=Math.max(1,deltaY)+"px";if(evt.xy.x<this.mouseDragStart.x){this.zoomBox.style.left=evt.xy.x+"px";}
+if(evt.xy.y<this.mouseDragStart.y){this.zoomBox.style.top=evt.xy.y+"px";}}else{var deltaX=this.mouseDragStart.x-evt.xy.x;var deltaY=this.mouseDragStart.y-evt.xy.y;var size=this.map.getSize();var newXY=new OpenLayers.Pixel(size.w/2+deltaX,size.h/2+deltaY);var newCenter=this.map.getLonLatFromViewPortPx(newXY);this.map.setCenter(newCenter,null,true);this.mouseDragStart=evt.xy.clone();this.map.div.style.cursor="move";}
+this.performedDrag=true;}},defaultMouseUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
+if(this.zoomBox){this.zoomBoxEnd(evt);}else{if(this.performedDrag){this.map.setCenter(this.map.center);}}
+document.onselectstart=null;this.mouseDragStart=null;this.map.div.style.cursor="";},defaultMouseOut:function(evt){if(this.mouseDragStart!=null&&OpenLayers.Util.mouseLeft(evt,this.map.div)){if(this.zoomBox){this.removeZoomBox();}
+this.mouseDragStart=null;}},defaultWheelUp:function(evt){if(this.map.getZoom()<=this.map.getNumZoomLevels()){this.map.setCenter(this.map.getLonLatFromPixel(evt.xy),this.map.getZoom()+1);}},defaultWheelDown:function(evt){if(this.map.getZoom()>0){this.map.setCenter(this.map.getLonLatFromPixel(evt.xy),this.map.getZoom()-1);}},zoomBoxEnd:function(evt){if(this.mouseDragStart!=null){if(Math.abs(this.mouseDragStart.x-evt.xy.x)>5||Math.abs(this.mouseDragStart.y-evt.xy.y)>5){var start=this.map.getLonLatFromViewPortPx(this.mouseDragStart);var end=this.map.getLonLatFromViewPortPx(evt.xy);var top=Math.max(start.lat,end.lat);var bottom=Math.min(start.lat,end.lat);var left=Math.min(start.lon,end.lon);var right=Math.max(start.lon,end.lon);var bounds=new OpenLayers.Bounds(left,bottom,right,top);this.map.zoomToExtent(bounds);}else{var end=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(new OpenLayers.LonLat((end.lon),(end.lat)),this.map.getZoom()+1);}
+this.removeZoomBox();}},removeZoomBox:function(){this.map.viewPortDiv.removeChild(this.zoomBox);this.zoomBox=null;},onWheelEvent:function(e){var inMap=false;var elem=OpenLayers.Event.element(e);while(elem!=null){if(this.map&&elem==this.map.div){inMap=true;break;}
+elem=elem.parentNode;}
+if(inMap){var delta=0;if(!e){e=window.event;}
+if(e.wheelDelta){delta=e.wheelDelta/120;if(window.opera&&window.opera.version()<9.2){delta=-delta;}}else if(e.detail){delta=-e.detail/3;}
+if(delta){e.xy=this.mousePosition;if(delta<0){this.defaultWheelDown(e);}else{this.defaultWheelUp(e);}}
+OpenLayers.Event.stop(e);}},CLASS_NAME:"OpenLayers.Control.MouseDefaults"});OpenLayers.Control.MousePosition=OpenLayers.Class(OpenLayers.Control,{autoActivate:true,element:null,prefix:'',separator:', ',suffix:'',numDigits:5,granularity:10,emptyString:null,lastXy:null,displayProjection:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){this.deactivate();OpenLayers.Control.prototype.destroy.apply(this,arguments);},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){this.map.events.register('mousemove',this,this.redraw);this.map.events.register('mouseout',this,this.reset);this.redraw();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.map.events.unregister('mousemove',this,this.redraw);this.map.events.unregister('mouseout',this,this.reset);this.element.innerHTML="";return true;}else{return false;}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.element){this.div.left="";this.div.top="";this.element=this.div;}
+return this.div;},redraw:function(evt){var lonLat;if(evt==null){this.reset();return;}else{if(this.lastXy==null||Math.abs(evt.xy.x-this.lastXy.x)>this.granularity||Math.abs(evt.xy.y-this.lastXy.y)>this.granularity)
+{this.lastXy=evt.xy;return;}
+lonLat=this.map.getLonLatFromPixel(evt.xy);if(!lonLat){return;}
+if(this.displayProjection){lonLat.transform(this.map.getProjectionObject(),this.displayProjection);}
+this.lastXy=evt.xy;}
+var newHtml=this.formatOutput(lonLat);if(newHtml!=this.element.innerHTML){this.element.innerHTML=newHtml;}},reset:function(evt){if(this.emptyString!=null){this.element.innerHTML=this.emptyString;}},formatOutput:function(lonLat){var digits=parseInt(this.numDigits);var newHtml=this.prefix+
+lonLat.lon.toFixed(digits)+
+this.separator+
+lonLat.lat.toFixed(digits)+
+this.suffix;return newHtml;},CLASS_NAME:"OpenLayers.Control.MousePosition"});OpenLayers.Control.Pan=OpenLayers.Class(OpenLayers.Control,{slideFactor:50,direction:null,type:OpenLayers.Control.TYPE_BUTTON,initialize:function(direction,options){this.direction=direction;this.CLASS_NAME+=this.direction;OpenLayers.Control.prototype.initialize.apply(this,[options]);},trigger:function(){switch(this.direction){case OpenLayers.Control.Pan.NORTH:this.map.pan(0,-this.slideFactor);break;case OpenLayers.Control.Pan.SOUTH:this.map.pan(0,this.slideFactor);break;case OpenLayers.Control.Pan.WEST:this.map.pan(-this.slideFactor,0);break;case OpenLayers.Control.Pan.EAST:this.map.pan(this.slideFactor,0);break;}},CLASS_NAME:"OpenLayers.Control.Pan"});OpenLayers.Control.Pan.NORTH="North";OpenLayers.Control.Pan.SOUTH="South";OpenLayers.Control.Pan.EAST="East";OpenLayers.Control.Pan.WEST="West";OpenLayers.Control.PanZoom=OpenLayers.Class(OpenLayers.Control,{slideFactor:50,slideRatio:null,buttons:null,position:null,initialize:function(options){this.position=new OpenLayers.Pixel(OpenLayers.Control.PanZoom.X,OpenLayers.Control.PanZoom.Y);OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this,arguments);this.removeButtons();this.buttons=null;this.position=null;},draw:function(px){OpenLayers.Control.prototype.draw.apply(this,arguments);px=this.position;this.buttons=[];var sz=new OpenLayers.Size(18,18);var centered=new OpenLayers.Pixel(px.x+sz.w/2,px.y);this._addButton("panup","north-mini.png",centered,sz);px.y=centered.y+sz.h;this._addButton("panleft","west-mini.png",px,sz);this._addButton("panright","east-mini.png",px.add(sz.w,0),sz);this._addButton("pandown","south-mini.png",centered.add(0,sz.h*2),sz);this._addButton("zoomin","zoom-plus-mini.png",centered.add(0,sz.h*3+5),sz);this._addButton("zoomworld","zoom-world-mini.png",centered.add(0,sz.h*4+5),sz);this._addButton("zoomout","zoom-minus-mini.png",centered.add(0,sz.h*5+5),sz);return this.div;},_addButton:function(id,img,xy,sz){var imgLocation=OpenLayers.Util.getImagesLocation()+img;var btn=OpenLayers.Util.createAlphaImageDiv(this.id+"_"+id,xy,sz,imgLocation,"absolute");this.div.appendChild(btn);OpenLayers.Event.observe(btn,"mousedown",OpenLayers.Function.bindAsEventListener(this.buttonDown,btn));OpenLayers.Event.observe(btn,"dblclick",OpenLayers.Function.bindAsEventListener(this.doubleClick,btn));OpenLayers.Event.observe(btn,"click",OpenLayers.Function.bindAsEventListener(this.doubleClick,btn));btn.action=id;btn.map=this.map;if(!this.slideRatio){var slideFactorPixels=this.slideFactor;var getSlideFactor=function(){return slideFactorPixels;};}else{var slideRatio=this.slideRatio;var getSlideFactor=function(dim){return this.map.getSize()[dim]*slideRatio;};}
+btn.getSlideFactor=getSlideFactor;this.buttons.push(btn);return btn;},_removeButton:function(btn){OpenLayers.Event.stopObservingElement(btn);btn.map=null;btn.getSlideFactor=null;this.div.removeChild(btn);OpenLayers.Util.removeItem(this.buttons,btn);},removeButtons:function(){for(var i=this.buttons.length-1;i>=0;--i){this._removeButton(this.buttons[i]);}},doubleClick:function(evt){OpenLayers.Event.stop(evt);return false;},buttonDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
+switch(this.action){case"panup":this.map.pan(0,-this.getSlideFactor("h"));break;case"pandown":this.map.pan(0,this.getSlideFactor("h"));break;case"panleft":this.map.pan(-this.getSlideFactor("w"),0);break;case"panright":this.map.pan(this.getSlideFactor("w"),0);break;case"zoomin":this.map.zoomIn();break;case"zoomout":this.map.zoomOut();break;case"zoomworld":this.map.zoomToMaxExtent();break;}
+OpenLayers.Event.stop(evt);},CLASS_NAME:"OpenLayers.Control.PanZoom"});OpenLayers.Control.PanZoom.X=4;OpenLayers.Control.PanZoom.Y=4;OpenLayers.Control.Panel=OpenLayers.Class(OpenLayers.Control,{controls:null,autoActivate:true,defaultControl:null,saveState:false,activeState:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.controls=[];this.activeState={};},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this,arguments);for(var i=this.controls.length-1;i>=0;i--){if(this.controls[i].events){this.controls[i].events.un({"activate":this.redraw,"deactivate":this.redraw,scope:this});}
+OpenLayers.Event.stopObservingElement(this.controls[i].panel_div);this.controls[i].panel_div=null;}
+this.activeState=null;},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){var control;for(var i=0,len=this.controls.length;i<len;i++){control=this.controls[i];if(control===this.defaultControl||(this.saveState&&this.activeState[control.id])){control.activate();}}
+if(this.saveState===true){this.defaultControl=null;}
+this.redraw();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){var control;for(var i=0,len=this.controls.length;i<len;i++){control=this.controls[i];this.activeState[control.id]=control.deactivate();}
+return true;}else{return false;}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.addControlsToMap(this.controls);return this.div;},redraw:function(){if(this.div.children.length>0){for(var l=this.div.children.length,i=l-1;i>=0;i--){this.div.removeChild(this.div.children[i]);}}
+this.div.innerHTML="";if(this.active){for(var i=0,len=this.controls.length;i<len;i++){var element=this.controls[i].panel_div;if(this.controls[i].active){element.className=this.controls[i].displayClass+"ItemActive";}else{element.className=this.controls[i].displayClass+"ItemInactive";}
+this.div.appendChild(element);}}},activateControl:function(control){if(!this.active){return false;}
+if(control.type==OpenLayers.Control.TYPE_BUTTON){control.trigger();this.redraw();return;}
+if(control.type==OpenLayers.Control.TYPE_TOGGLE){if(control.active){control.deactivate();}else{control.activate();}
+this.redraw();return;}
+var c;for(var i=0,len=this.controls.length;i<len;i++){c=this.controls[i];if(c!=control&&(c.type===OpenLayers.Control.TYPE_TOOL||c.type==null)){c.deactivate();}}
+control.activate();},addControls:function(controls){if(!(controls instanceof Array)){controls=[controls];}
+this.controls=this.controls.concat(controls);for(var i=0,len=controls.length;i<len;i++){var element=document.createElement("div");controls[i].panel_div=element;if(controls[i].title!=""){controls[i].panel_div.title=controls[i].title;}
+OpenLayers.Event.observe(controls[i].panel_div,"click",OpenLayers.Function.bind(this.onClick,this,controls[i]));OpenLayers.Event.observe(controls[i].panel_div,"dblclick",OpenLayers.Function.bind(this.onDoubleClick,this,controls[i]));OpenLayers.Event.observe(controls[i].panel_div,"mousedown",OpenLayers.Function.bindAsEventListener(OpenLayers.Event.stop));}
+if(this.map){this.addControlsToMap(controls);this.redraw();}},addControlsToMap:function(controls){var control;for(var i=0,len=controls.length;i<len;i++){control=controls[i];if(control.autoActivate===true){control.autoActivate=false;this.map.addControl(control);control.autoActivate=true;}else{this.map.addControl(control);control.deactivate();}
+control.events.on({"activate":this.redraw,"deactivate":this.redraw,scope:this});}},onClick:function(ctrl,evt){OpenLayers.Event.stop(evt?evt:window.event);this.activateControl(ctrl);},onDoubleClick:function(ctrl,evt){OpenLayers.Event.stop(evt?evt:window.event);},getControlsBy:function(property,match){var test=(typeof match.test=="function");var found=OpenLayers.Array.filter(this.controls,function(item){return item[property]==match||(test&&match.test(item[property]));});return found;},getControlsByName:function(match){return this.getControlsBy("name",match);},getControlsByClass:function(match){return this.getControlsBy("CLASS_NAME",match);},CLASS_NAME:"OpenLayers.Control.Panel"});OpenLayers.Control.Scale=OpenLayers.Class(OpenLayers.Control,{element:null,geodesic:false,initialize:function(element,options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.element=OpenLayers.Util.getElement(element);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.element){this.element=document.createElement("div");this.div.appendChild(this.element);}
+this.map.events.register('moveend',this,this.updateScale);this.updateScale();return this.div;},updateScale:function(){var scale;if(this.geodesic===true){var units=this.map.getUnits();if(!units){return;}
+var inches=OpenLayers.INCHES_PER_UNIT;scale=(this.map.getGeodesicPixelSize().w||0.000001)*inches["km"]*OpenLayers.DOTS_PER_INCH;}else{scale=this.map.getScale();}
+if(!scale){return;}
+if(scale>=9500&&scale<=950000){scale=Math.round(scale/1000)+"K";}else if(scale>=950000){scale=Math.round(scale/1000000)+"M";}else{scale=Math.round(scale);}
+this.element.innerHTML=OpenLayers.i18n("scale",{'scaleDenom':scale});},CLASS_NAME:"OpenLayers.Control.Scale"});OpenLayers.Control.ScaleLine=OpenLayers.Class(OpenLayers.Control,{maxWidth:100,topOutUnits:"km",topInUnits:"m",bottomOutUnits:"mi",bottomInUnits:"ft",eTop:null,eBottom:null,geodesic:false,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,[options]);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.eTop){this.eTop=document.createElement("div");this.eTop.className=this.displayClass+"Top";var theLen=this.topInUnits.length;this.div.appendChild(this.eTop);if((this.topOutUnits=="")||(this.topInUnits=="")){this.eTop.style.visibility="hidden";}else{this.eTop.style.visibility="visible";}
+this.eBottom=document.createElement("div");this.eBottom.className=this.displayClass+"Bottom";this.div.appendChild(this.eBottom);if((this.bottomOutUnits=="")||(this.bottomInUnits=="")){this.eBottom.style.visibility="hidden";}else{this.eBottom.style.visibility="visible";}}
+this.map.events.register('moveend',this,this.update);this.update();return this.div;},getBarLen:function(maxLen){var digits=parseInt(Math.log(maxLen)/Math.log(10));var pow10=Math.pow(10,digits);var firstChar=parseInt(maxLen/pow10);var barLen;if(firstChar>5){barLen=5;}else if(firstChar>2){barLen=2;}else{barLen=1;}
+return barLen*pow10;},update:function(){var res=this.map.getResolution();if(!res){return;}
+var curMapUnits=this.map.getUnits();var inches=OpenLayers.INCHES_PER_UNIT;var maxSizeData=this.maxWidth*res*inches[curMapUnits];var geodesicRatio=1;if(this.geodesic===true){var maxSizeGeodesic=(this.map.getGeodesicPixelSize().w||0.000001)*this.maxWidth;var maxSizeKilometers=maxSizeData/inches["km"];geodesicRatio=maxSizeGeodesic/maxSizeKilometers;maxSizeData*=geodesicRatio;}
+var topUnits;var bottomUnits;if(maxSizeData>100000){topUnits=this.topOutUnits;bottomUnits=this.bottomOutUnits;}else{topUnits=this.topInUnits;bottomUnits=this.bottomInUnits;}
+var topMax=maxSizeData/inches[topUnits];var bottomMax=maxSizeData/inches[bottomUnits];var topRounded=this.getBarLen(topMax);var bottomRounded=this.getBarLen(bottomMax);topMax=topRounded/inches[curMapUnits]*inches[topUnits];bottomMax=bottomRounded/inches[curMapUnits]*inches[bottomUnits];var topPx=topMax/res/geodesicRatio;var bottomPx=bottomMax/res/geodesicRatio;if(this.eBottom.style.visibility=="visible"){this.eBottom.style.width=Math.round(bottomPx)+"px";this.eBottom.innerHTML=bottomRounded+" "+bottomUnits;}
+if(this.eTop.style.visibility=="visible"){this.eTop.style.width=Math.round(topPx)+"px";this.eTop.innerHTML=topRounded+" "+topUnits;}},CLASS_NAME:"OpenLayers.Control.ScaleLine"});OpenLayers.Control.ZoomIn=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){this.map.zoomIn();},CLASS_NAME:"OpenLayers.Control.ZoomIn"});OpenLayers.Control.ZoomOut=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){this.map.zoomOut();},CLASS_NAME:"OpenLayers.Control.ZoomOut"});OpenLayers.Control.ZoomToMaxExtent=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){if(this.map){this.map.zoomToMaxExtent();}},CLASS_NAME:"OpenLayers.Control.ZoomToMaxExtent"});OpenLayers.Event={observers:false,KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,element:function(event){return event.target||event.srcElement;},isLeftClick:function(event){return(((event.which)&&(event.which==1))||((event.button)&&(event.button==1)));},isRightClick:function(event){return(((event.which)&&(event.which==3))||((event.button)&&(event.button==2)));},stop:function(event,allowDefault){if(!allowDefault){if(event.preventDefault){event.preventDefault();}else{event.returnValue=false;}}
+if(event.stopPropagation){event.stopPropagation();}else{event.cancelBubble=true;}},findElement:function(event,tagName){var element=OpenLayers.Event.element(event);while(element.parentNode&&(!element.tagName||(element.tagName.toUpperCase()!=tagName.toUpperCase()))){element=element.parentNode;}
+return element;},observe:function(elementParam,name,observer,useCapture){var element=OpenLayers.Util.getElement(elementParam);useCapture=useCapture||false;if(name=='keypress'&&(navigator.appVersion.match(/Konqueror|Safari|KHTML/)||element.attachEvent)){name='keydown';}
+if(!this.observers){this.observers={};}
+if(!element._eventCacheID){var idPrefix="eventCacheID_";if(element.id){idPrefix=element.id+"_"+idPrefix;}
+element._eventCacheID=OpenLayers.Util.createUniqueID(idPrefix);}
+var cacheID=element._eventCacheID;if(!this.observers[cacheID]){this.observers[cacheID]=[];}
+this.observers[cacheID].push({'element':element,'name':name,'observer':observer,'useCapture':useCapture});if(element.addEventListener){element.addEventListener(name,observer,useCapture);}else if(element.attachEvent){element.attachEvent('on'+name,observer);}},stopObservingElement:function(elementParam){var element=OpenLayers.Util.getElement(elementParam);var cacheID=element._eventCacheID;this._removeElementObservers(OpenLayers.Event.observers[cacheID]);},_removeElementObservers:function(elementObservers){if(elementObservers){for(var i=elementObservers.length-1;i>=0;i--){var entry=elementObservers[i];var args=new Array(entry.element,entry.name,entry.observer,entry.useCapture);var removed=OpenLayers.Event.stopObserving.apply(this,args);}}},stopObserving:function(elementParam,name,observer,useCapture){useCapture=useCapture||false;var element=OpenLayers.Util.getElement(elementParam);var cacheID=element._eventCacheID;if(name=='keypress'){if(navigator.appVersion.match(/Konqueror|Safari|KHTML/)||element.detachEvent){name='keydown';}}
+var foundEntry=false;var elementObservers=OpenLayers.Event.observers[cacheID];if(elementObservers){var i=0;while(!foundEntry&&i<elementObservers.length){var cacheEntry=elementObservers[i];if((cacheEntry.name==name)&&(cacheEntry.observer==observer)&&(cacheEntry.useCapture==useCapture)){elementObservers.splice(i,1);if(elementObservers.length==0){delete OpenLayers.Event.observers[cacheID];}
+foundEntry=true;break;}
+i++;}}
+if(foundEntry){if(element.removeEventListener){element.removeEventListener(name,observer,useCapture);}else if(element&&element.detachEvent){element.detachEvent('on'+name,observer);}}
+return foundEntry;},unloadCache:function(){if(OpenLayers.Event&&OpenLayers.Event.observers){for(var cacheID in OpenLayers.Event.observers){var elementObservers=OpenLayers.Event.observers[cacheID];OpenLayers.Event._removeElementObservers.apply(this,[elementObservers]);}
+OpenLayers.Event.observers=false;}},CLASS_NAME:"OpenLayers.Event"};OpenLayers.Event.observe(window,'unload',OpenLayers.Event.unloadCache,false);if(window.Event){OpenLayers.Util.applyDefaults(window.Event,OpenLayers.Event);}else{var Event=OpenLayers.Event;}
+OpenLayers.Events=OpenLayers.Class({BROWSER_EVENTS:["mouseover","mouseout","mousedown","mouseup","mousemove","click","dblclick","rightclick","dblrightclick","resize","focus","blur"],listeners:null,object:null,element:null,eventTypes:null,eventHandler:null,fallThrough:null,includeXY:false,clearMouseListener:null,initialize:function(object,element,eventTypes,fallThrough,options){OpenLayers.Util.extend(this,options);this.object=object;this.fallThrough=fallThrough;this.listeners={};this.eventHandler=OpenLayers.Function.bindAsEventListener(this.handleBrowserEvent,this);this.clearMouseListener=OpenLayers.Function.bind(this.clearMouseCache,this);this.eventTypes=[];if(eventTypes!=null){for(var i=0,len=eventTypes.length;i<len;i++){this.addEventType(eventTypes[i]);}}
+if(element!=null){this.attachToElement(element);}},destroy:function(){if(this.element){OpenLayers.Event.stopObservingElement(this.element);if(this.element.hasScrollEvent){OpenLayers.Event.stopObserving(window,"scroll",this.clearMouseListener);}}
+this.element=null;this.listeners=null;this.object=null;this.eventTypes=null;this.fallThrough=null;this.eventHandler=null;},addEventType:function(eventName){if(!this.listeners[eventName]){this.eventTypes.push(eventName);this.listeners[eventName]=[];}},attachToElement:function(element){if(this.element){OpenLayers.Event.stopObservingElement(this.element);}
+this.element=element;for(var i=0,len=this.BROWSER_EVENTS.length;i<len;i++){var eventType=this.BROWSER_EVENTS[i];this.addEventType(eventType);OpenLayers.Event.observe(element,eventType,this.eventHandler);}
+OpenLayers.Event.observe(element,"dragstart",OpenLayers.Event.stop);},on:function(object){for(var type in object){if(type!="scope"){this.register(type,object.scope,object[type]);}}},register:function(type,obj,func){if((func!=null)&&(OpenLayers.Util.indexOf(this.eventTypes,type)!=-1)){if(obj==null){obj=this.object;}
+var listeners=this.listeners[type];listeners.push({obj:obj,func:func});}},registerPriority:function(type,obj,func){if(func!=null){if(obj==null){obj=this.object;}
+var listeners=this.listeners[type];if(listeners!=null){listeners.unshift({obj:obj,func:func});}}},un:function(object){for(var type in object){if(type!="scope"){this.unregister(type,object.scope,object[type]);}}},unregister:function(type,obj,func){if(obj==null){obj=this.object;}
+var listeners=this.listeners[type];if(listeners!=null){for(var i=0,len=listeners.length;i<len;i++){if(listeners[i].obj==obj&&listeners[i].func==func){listeners.splice(i,1);break;}}}},remove:function(type){if(this.listeners[type]!=null){this.listeners[type]=[];}},triggerEvent:function(type,evt){var listeners=this.listeners[type];if(!listeners||listeners.length==0){return;}
+if(evt==null){evt={};}
+evt.object=this.object;evt.element=this.element;if(!evt.type){evt.type=type;}
+var listeners=listeners.slice(),continueChain;for(var i=0,len=listeners.length;i<len;i++){var callback=listeners[i];continueChain=callback.func.apply(callback.obj,[evt]);if((continueChain!=undefined)&&(continueChain==false)){break;}}
+if(!this.fallThrough){OpenLayers.Event.stop(evt,true);}
+return continueChain;},handleBrowserEvent:function(evt){if(this.includeXY){evt.xy=this.getMousePosition(evt);}
+this.triggerEvent(evt.type,evt);},clearMouseCache:function(){this.element.scrolls=null;this.element.lefttop=null;this.element.offsets=null;},getMousePosition:function(evt){if(!this.includeXY){this.clearMouseCache();}else if(!this.element.hasScrollEvent){OpenLayers.Event.observe(window,"scroll",this.clearMouseListener);this.element.hasScrollEvent=true;}
+if(!this.element.scrolls){this.element.scrolls=[(document.documentElement.scrollLeft||document.body.scrollLeft),(document.documentElement.scrollTop||document.body.scrollTop)];}
+if(!this.element.lefttop){this.element.lefttop=[(document.documentElement.clientLeft||0),(document.documentElement.clientTop||0)];}
+if(!this.element.offsets){this.element.offsets=OpenLayers.Util.pagePosition(this.element);this.element.offsets[0]+=this.element.scrolls[0];this.element.offsets[1]+=this.element.scrolls[1];}
+return new OpenLayers.Pixel((evt.clientX+this.element.scrolls[0])-this.element.offsets[0]
+-this.element.lefttop[0],(evt.clientY+this.element.scrolls[1])-this.element.offsets[1]
+-this.element.lefttop[1]);},CLASS_NAME:"OpenLayers.Events"});OpenLayers.Format=OpenLayers.Class({options:null,externalProjection:null,internalProjection:null,data:null,keepData:false,initialize:function(options){OpenLayers.Util.extend(this,options);this.options=options;},destroy:function(){},read:function(data){OpenLayers.Console.userError(OpenLayers.i18n("readNotImplemented"));},write:function(object){OpenLayers.Console.userError(OpenLayers.i18n("writeNotImplemented"));},CLASS_NAME:"OpenLayers.Format"});OpenLayers.Lang["ar"]=OpenLayers.Util.applyDefaults({'permalink':"وصلة دائمة",'baseLayer':"الطبقة الاساسية",'readNotImplemented':"القراءة غير محققة.",'writeNotImplemented':"الكتابة غير محققة",'errorLoadingGML':"خطأ عند تحميل الملف جي ام ال ${url}",'scale':"النسبة = 1 : ${scaleDenom}",'W':"غ",'E':"شر",'N':"شم",'S':"ج"});OpenLayers.Lang["be-tarask"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Неапрацаваны вынік запыту ${statusText}",'permalink':"Сталая спасылка",'overlays':"Слаі",'baseLayer':"Базавы слой",'sameProjection':"Аглядная мапа працуе толькі калі яна мае тую ж праекцыю, што і асноўная мапа",'readNotImplemented':"Функцыянальнасьць чытаньня ня створаная.",'writeNotImplemented':"Функцыянальнасьць запісу ня створаная.",'noFID':"Немагчыма абнавіць магчымасьць, для якога не існуе FID.",'errorLoadingGML':"Памылка загрузкі файла GML ${url}",'browserNotSupported':"Ваш браўзэр не падтрымлівае вэктарную графіку. У цяперашні момант падтрымліваюцца: ${renderers}",'componentShouldBe':"addFeatures : кампанэнт павінен быць ${geomType}",'getFeatureError':"getFeatureFromEvent выкліканы для слоя бяз рэндэру. Звычайна гэта азначае, што Вы зьнішчылі слой, але пакінулі зьвязаны зь ім апрацоўшчык.",'minZoomLevelError':"Уласьцівасьць minZoomLevel прызначана толькі для выкарыстаньня са слаямі вытворнымі ад FixedZoomLevels. Тое, што  гэты wfs-слой правяраецца на minZoomLevel — рэха прошлага. Але мы ня можам выдаліць гэтую магчымасьць, таму што ад яе залежаць некаторыя заснаваныя на OL дастасаваньні. Тым ня менш, праверка minZoomLevel будзе выдаленая ў вэрсіі 3.0. Калі ласка, выкарыстоўваеце замест яе ўстаноўкі мінімальнага/максымальнага памераў, як апісана тут: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS-транзакцыя: ПОСЬПЕХ ${response}",'commitFailed':"WFS-транзакцыя: ПАМЫЛКА ${response}",'googleWarning':"Не атрымалася загрузіць слой Google. \x3cbr\x3e\x3cbr\x3eКаб пазбавіцца гэтага паведамленьня, выберыце новы базавы слой у сьпісе ў верхнім правым куце.\x3cbr\x3e\x3cbr\x3e Хутчэй за ўсё, прычына ў тым, што скрыпт бібліятэкі Google Maps ня быў уключаныя альбо не ўтрымлівае слушны API-ключ для Вашага сайта.\x3cbr\x3e\x3cbr\x3eРаспрацоўшчыкам: Для таго, каб даведацца як зрабіць так, каб усё працавала, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eнацісьніце тут\x3c/a\x3e",'getLayerWarning':"Немагчыма загрузіць слой ${layerType}.\x3cbr\x3e\x3cbr\x3eКаб пазбавіцца гэтага паведамленьня, выберыце новы базавы слой у сьпісе ў верхнім правым куце.\x3cbr\x3e\x3cbr\x3eХутчэй за ўсё, прычына ў тым, што скрыпт бібліятэкі ${layerLib} ня быў слушна ўключаны.\x3cbr\x3e\x3cbr\x3eРаспрацоўшчыкам: Для таго, каб даведацца як зрабіць так, каб усё працавала, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eнацісьніце тут\x3c/a\x3e",'scale':"Маштаб = 1 : ${scaleDenom}",'W':"З",'E':"У",'N':"Пн",'S':"Пд",'layerAlreadyAdded':"Вы паспрабавалі дадаць слой ${layerName} на мапу, але ён ужо дададзены",'reprojectDeprecated':"Вы выкарыстоўваеце ўстаноўку \'reproject\' для слоя ${layerName}. Гэтая ўстаноўка зьяўляецца састарэлай: яна выкарыстоўвалася для падтрымкі паказу зьвестак на камэрцыйных базавых мапах, але гэта функцыя цяпер рэалізаваная ў убудаванай падтрымцы сфэрычнай праекцыі Мэркатара. Дадатковая інфармацыя ёсьць на http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Гэты мэтад састарэлы і будзе выдалены ў вэрсіі 3.0. Калі ласка, замест яго выкарыстоўвайце ${newMethod}.",'boundsAddError':"Вам неабходна падаць абодва значэньні x і y для функцыі складаньня.",'lonlatAddError':"Вам неабходна падаць абодва значэньні lon і lat для функцыі складаньня.",'pixelAddError':"Вам неабходна падаць абодва значэньні x і y для функцыі складаньня.",'unsupportedGeometryType':"Тып геамэтрыі не падтрымліваецца: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition failed: верагодна элемэнт з ідэнтыфікатарам ${elemId} займае няслушнае месца.",'filterEvaluateNotImplemented':"evaluate не рэалізаваны для гэтага тыпу фільтру."});OpenLayers.Lang["bg"]=OpenLayers.Util.applyDefaults({'permalink':"Постоянна препратка",'baseLayer':"Основен слой",'errorLoadingGML':"Грешка при зареждане на GML файл ${url}",'scale':"Мащаб = 1 : ${scaleDenom}",'layerAlreadyAdded':"Опитахте да добавите слой ${layerName} в картата, но той вече е добавен",'methodDeprecated':"Този метод е остарял и ще бъде премахват в 3.0. Вместо него използвайте ${newMethod}."});OpenLayers.Lang["br"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Distro evel reked anveret ${statusText}",'permalink':"Peurliamm",'overlays':"Gwiskadoù",'baseLayer':"Gwiskad diazez",'sameProjection':"Ne\'z ar gartenn lec\'hiañ en-dro nemet pa vez heñvel ar banndres anezhi ha hini ar gartenn bennañ",'readNotImplemented':"N\'eo ket emplementet al lenn.",'writeNotImplemented':"N\'eo ket emplementet ar skrivañ.",'noFID':"N\'haller ket hizivaat un elfenn ma n\'eus ket a niverenn-anaout (FID) eviti.",'errorLoadingGML':"Fazi e-ser kargañ ar restr GML ${url}",'browserNotSupported':"N\'eo ket skoret an daskor vektorel gant ho merdeer. Setu aze an daskorerioù skoret evit ar poent :\n${renderers}",'componentShouldBe':"addFeatures : bez\' e tlefe ar parzh besañ eus ar seurt ${geomType}",'getFeatureError':"Galvet eo bet getFeatureFromEvent called war ur gwiskad hep daskorer. Kement-se a dalvez ez eus bet freuzet ur gwiskad hag hoc\'h eus miret un embreger bennak stag outañ.",'minZoomLevelError':"Ne zleer implijout ar perzh minZoomLevel nemet evit gwiskadoù FixedZoomLevels-descendent. Ar fed ma wiria ar gwiskad WHS-se hag-eñ ez eus eus minZoomLevel zo un aspadenn gozh. Koulskoude n\'omp ket evit e ziverkañ kuit da derriñ arloadoù diazezet war OL a c\'hallfe bezañ stag outañ. Setu perak eo dispredet -- Lamet kuit e vo ar gwiriañ minZoomLevel a-is er stumm 3.0. Ober gant an arventennoù bihanañ/brasañ evel deskrivet amañ e plas : http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Treuzgread WFS : MAT EO ${response}",'commitFailed':"Treuzgread WFS Transaction: C\'HWITET ${response}",'googleWarning':"N\'eus ket bet gallet kargañ ar gwiskad Google ent reizh.\x3cbr\x3e\x3cbr\x3eEvit en em zizober eus ar c\'hemenn-mañ, dibabit ur BaseLayer nevez en diuzer gwiskadoù er c\'horn dehoù el laez.\x3cbr\x3e\x3cbr\x3eSur a-walc\'h eo peogwir n\'eo ket bet ensoc\'het levraoueg Google Maps pe neuze ne glot ket an alc\'hwez API gant ho lec\'hienn.\x3cbr\x3e\x3cbr\x3eDiorroerien : Evit reizhañ an dra-se, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclick here\x3c/a\x3e",'getLayerWarning':"N\'haller ket kargañ ar gwiskad ${layerType} ent reizh.\x3cbr\x3e\x3cbr\x3eEvit en em zizober eus ar c\'hemenn-mañ, dibabit ur BaseLayer nevez en diuzer gwiskadoù er c\'horn dehoù el laez.\x3cbr\x3e\x3cbr\x3eSur a-walc\'h eo peogwir n\'eo ket bet ensoc\'het mat al levraoueg ${layerLib}.\x3cbr\x3e\x3cbr\x3eDiorroerien : Evit gouzout penaos reizhañ an dra-se, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclick here\x3c/a\x3e",'scale':"Skeul = 1 : ${scaleDenom}",'W':"K",'E':"R",'N':"N",'S':"S",'layerAlreadyAdded':"Klasket hoc\'h eus ouzhpennañ ar gwiskad : ${layerName} d\'ar gartenn, met ouzhpennet e oa bet c\'hoazh",'reprojectDeprecated':"Emaoc\'h oc\'h implijout an dibarzh \'reproject\' war ar gwiskad ${layerName}. Dispredet eo an dibarzh-mañ : bet eo hag e talveze da ziskwel roadennoù war-c\'horre kartennoù diazez kenwerzhel, un dra hag a c\'haller ober bremañ gant an arc\'hwel dre skor banndres boullek Mercator. Muioc\'h a ditouroù a c\'haller da gaout war http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Dispredet eo an daore-se ha tennet e vo kuit eus ar stumm 3.0. Grit gant ${newMethod} e plas.",'boundsAddError':"Rekis eo tremen an div dalvoudenn x ha y d\'an arc\'hwel add.",'lonlatAddError':"Rekis eo tremen an div dalvoudenn hedred ha ledred d\'an arc\'hwel add.",'pixelAddError':"Rekis eo tremen an div dalvoudenn x ha y d\'an arc\'hwel add.",'unsupportedGeometryType':"Seurt mentoniezh anskoret : ${geomType}",'pagePositionFailed':"C\'hwitet eo OpenLayers.Util.pagePosition : marteze emañ lec\'hiet fall an elfenn id ${elemId}.",'filterEvaluateNotImplemented':"N\'eo ket bet emplementet ar priziañ evit seurt siloù c\'hoazh."});OpenLayers.Lang["el"]=OpenLayers.Util.applyDefaults({'scale':"Κλίμακα ~ 1 : ${scaleDenom}"});OpenLayers.Lang.en={'unhandledRequest':"Unhandled request return ${statusText}",'permalink':"Permalink",'overlays':"Overlays",'baseLayer':"Base Layer",'sameProjection':"The overview map only works when it is in the same projection as the main map",'readNotImplemented':"Read not implemented.",'writeNotImplemented':"Write not implemented.",'noFID':"Can't update a feature for which there is no FID.",'errorLoadingGML':"Error in loading GML file ${url}",'browserNotSupported':"Your browser does not support vector rendering. Currently supported renderers are:\n${renderers}",'componentShouldBe':"addFeatures : component should be an ${geomType}",'getFeatureError':"getFeatureFromEvent called on layer with no renderer. This usually means you "+"destroyed a layer, but not some handler which is associated with it.",'minZoomLevelError':"The minZoomLevel property is only intended for use "+"with the FixedZoomLevels-descendent layers. That this "+"wfs layer checks for minZoomLevel is a relic of the"+"past. We cannot, however, remove it without possibly "+"breaking OL based applications that may depend on it."+" Therefore we are deprecating it -- the minZoomLevel "+"check below will be removed at 3.0. Please instead "+"use min/max resolution setting as described here: "+"http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS Transaction: SUCCESS ${response}",'commitFailed':"WFS Transaction: FAILED ${response}",'googleWarning':"The Google Layer was unable to load correctly.<br><br>"+"To get rid of this message, select a new BaseLayer "+"in the layer switcher in the upper-right corner.<br><br>"+"Most likely, this is because the Google Maps library "+"script was either not included, or does not contain the "+"correct API key for your site.<br><br>"+"Developers: For help getting this working correctly, "+"<a href='http://trac.openlayers.org/wiki/Google' "+"target='_blank'>click here</a>",'getLayerWarning':"The ${layerType} Layer was unable to load correctly.<br><br>"+"To get rid of this message, select a new BaseLayer "+"in the layer switcher in the upper-right corner.<br><br>"+"Most likely, this is because the ${layerLib} library "+"script was not correctly included.<br><br>"+"Developers: For help getting this working correctly, "+"<a href='http://trac.openlayers.org/wiki/${layerLib}' "+"target='_blank'>click here</a>",'scale':"Scale = 1 : ${scaleDenom}",'W':'W','E':'E','N':'N','S':'S','graticule':'Graticule','layerAlreadyAdded':"You tried to add the layer: ${layerName} to the map, but it has already been added",'reprojectDeprecated':"You are using the 'reproject' option "+"on the ${layerName} layer. This option is deprecated: "+"its use was designed to support displaying data over commercial "+"basemaps, but that functionality should now be achieved by using "+"Spherical Mercator support. More information is available from "+"http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"This method has been deprecated and will be removed in 3.0. "+"Please use ${newMethod} instead.",'boundsAddError':"You must pass both x and y values to the add function.",'lonlatAddError':"You must pass both lon and lat values to the add function.",'pixelAddError':"You must pass both x and y values to the add function.",'unsupportedGeometryType':"Unsupported geometry type: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition failed: element with id ${elemId} may be misplaced.",'filterEvaluateNotImplemented':"evaluate is not implemented for this filter type.",'end':''};OpenLayers.Lang["fi"]=OpenLayers.Util.applyDefaults({'permalink':"Ikilinkki",'overlays':"Kerrokset",'baseLayer':"Peruskerros",'sameProjection':"Yleiskuvakarttaa voi käyttää vain, kun sillä on sama projektio kuin pääkartalla.",'W':"L",'E':"I",'N':"P",'S':"E"});OpenLayers.Lang["fur"]=OpenLayers.Util.applyDefaults({'permalink':"Leam Permanent",'overlays':"Livei parsore",'baseLayer':"Livel di base",'browserNotSupported':"Il to sgarfadôr nol supuarte la renderizazion vetoriâl. Al moment a son supuartâts:\n${renderers}",'scale':"Scjale = 1 : ${scaleDenom}",'W':"O",'E':"E",'N':"N",'S':"S"});OpenLayers.Lang["gl"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Solicitude non xerada; a resposta foi: ${statusText}",'permalink':"Ligazón permanente",'overlays':"Capas superpostas",'baseLayer':"Capa base",'sameProjection':"A vista xeral do mapa só funciona cando está na mesma proxección có mapa principal",'readNotImplemented':"Lectura non implementada.",'writeNotImplemented':"Escritura non implementada.",'noFID':"Non se pode actualizar a funcionalidade para a que non hai FID.",'errorLoadingGML':"Erro ao cargar o ficheiro GML ${url}",'browserNotSupported':"O seu navegador non soporta a renderización de vectores. Os renderizadores soportados actualmente son:\n${renderers}",'componentShouldBe':"addFeatures: o compoñente debera ser de tipo ${geomType}",'getFeatureError':"getFeatureFromEvent ten sido chamado a unha capa sen renderizador. Isto normalmente significa que destruíu unha capa, mais non o executador que está asociado con ela.",'minZoomLevelError':"A propiedade minZoomLevel é só para uso conxuntamente coas capas FixedZoomLevels-descendent. O feito de que esa capa wfs verifique o minZoomLevel é unha reliquia do pasado. Non podemos, con todo, eliminala sen a posibilidade de non romper as aplicacións baseadas en OL que poidan depender dela. Por iso a estamos deixando obsoleta (a comprobación minZoomLevel de embaixo será eliminada na versión 3.0). Por favor, no canto diso use o axuste de resolución mín/máx tal e como está descrito aquí: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transacción WFS: ÉXITO ${response}",'commitFailed':"Transacción WFS: FALLIDA ${response}",'googleWarning':"A capa do Google non puido cargarse correctamente.\x3cbr\x3e\x3cbr\x3ePara evitar esta mensaxe, escolla unha nova capa base no seleccionador de capas na marxe superior dereita.\x3cbr\x3e\x3cbr\x3eProbablemente, isto acontece porque a escritura da libraría do Google Maps ou ben non foi incluída ou ben non contén a clave API correcta para o seu sitio.\x3cbr\x3e\x3cbr\x3eDesenvolvedores: para axudar a facer funcionar isto correctamente, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3epremede aquí\x3c/a\x3e",'getLayerWarning':"A capa ${layerType} foi incapaz de cargarse correctamente.\x3cbr\x3e\x3cbr\x3ePara evitar esta mensaxe, escolla unha nova capa base no seleccionador de capas na marxe superior dereita.\x3cbr\x3e\x3cbr\x3eProbablemente, isto acontece porque a escritura da libraría ${layerLib} non foi ben incluída.\x3cbr\x3e\x3cbr\x3eDesenvolvedores: para axudar a facer funcionar isto correctamente, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3epremede aquí\x3c/a\x3e",'scale':"Escala = 1 : ${scaleDenom}",'W':"O",'E':"L",'N':"N",'S':"S",'layerAlreadyAdded':"Intentou engadir a capa: ${layerName} ao mapa, pero xa fora engadida",'reprojectDeprecated':"Está usando a opción \"reproject\" na capa ${layerName}. Esta opción está obsoleta: o seu uso foi deseñado para a visualización de datos sobre mapas base comerciais, pero esta funcionalidade debera agora ser obtida utilizando a proxección Spherical Mercator. Hai dispoñible máis información en http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Este método está obsoleto e será eliminado na versión 3.0. Por favor, no canto deste use ${newMethod}.",'boundsAddError':"Debe achegar os valores x e y á función add.",'lonlatAddError':"Debe achegar tanto o valor lon coma o lat á función add.",'pixelAddError':"Debe achegar os valores x e y á función add.",'unsupportedGeometryType':"Tipo xeométrico non soportado: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition fallou: o elemento con id ${elemId} pode non estar na súa posición.",'filterEvaluateNotImplemented':"avaliar non está implementado para este tipo de filtro."});OpenLayers.Lang["gsw"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nit behandleti Aafrogsruckmäldig ${statusText}",'permalink':"Permalink",'overlays':"Iberlagerige",'baseLayer':"Grundcharte",'sameProjection':"D Ibersichts-Charte funktioniert nume, wänn si di glych Projäktion brucht wie d Hauptcharte",'readNotImplemented':"Läse nit implementiert.",'writeNotImplemented':"Schrybe nit implementiert.",'noFID':"E Feature, wu s kei FID derfir git, cha nit aktualisiert wäre.",'errorLoadingGML':"Fähler bim Lade vu dr GML-Datei ${url}",'browserNotSupported':"Dyy Browser unterstitzt kei Vektordarstellig. Aktuäll unterstitzti Renderer:\n${renderers}",'componentShouldBe':"addFeatures : Komponänt sott dr Typ ${geomType} syy",'getFeatureError':"getFeatureFromEvent isch uf eme Layer ohni Renderer ufgruefe wore. Des heisst normalerwys, ass Du e Layer kaputt gmacht hesch, aber nit dr Handler, wu derzue ghert.",'minZoomLevelError':"D minZoomLevel-Eigeschaft isch nume dänk fir d Layer, wu vu dr FixedZoomLevels abstamme. Ass dää wfs-Layer minZoomLevel prieft, scih e Relikt us dr Vergangeheit. Mir chenne s aber nit ändere ohni OL_basierti Aawändige villicht kaputt gehn, wu dervu abhänge.  Us däm Grund het die Funktion d Eigeschaft \'deprecated\' iberchuu. D minZoomLevel-Priefig unte wird in dr Version 3.0 usegnuu. Bitte verwänd statt däm e min/max-Uflesig wie s do bschriben isch: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS-Transaktion: ERFOLGRYCH ${response}",'commitFailed':"WFS-Transaktion: FÄHLGSCHLAA ${response}",'googleWarning':"Dr Google-Layer het nit korräkt chenne glade wäre.\x3cbr\x3e\x3cbr\x3eGo die Mäldig nimi z kriege, wehl e andere Hintergrundlayer us em LayerSwitcher im rächte obere Ecke.\x3cbr\x3e\x3cbr\x3eDää Fähler git s seli hyfig, wel s Skript vu dr Google-Maps-Bibliothek nit yybunde woren isch oder wel s kei giltige API-Schlissel fir Dyy URL din het.\x3cbr\x3e\x3cbr\x3eEntwickler: Fir Hilf zum korräkte Yybinde vum Google-Layer \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3edoo drucke\x3c/a\x3e",'getLayerWarning':"Dr ${layerType}-Layer het nit korräkt chenne glade wäre.\x3cbr\x3e\x3cbr\x3eGo die Mäldig nimi z kriege, wehl e andere Hintergrundlayer us em LayerSwitcher im rächte obere Ecke.\x3cbr\x3e\x3cbr\x3eDää Fähler git s seli hyfig, wel s Skript vu dr \'${layerLib}\'-Bibliothek nit yybunde woren isch oder wel s kei giltige API-Schlissel fir Dyy URL din het.\x3cbr\x3e\x3cbr\x3eEntwickler: Fir Hilf zum korräkte Yybinde vu Layer \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3edoo drucke\x3c/a\x3e",'scale':"Maßstab = 1 : ${scaleDenom}",'W':"W",'E':"O",'N':"N",'S':"S",'layerAlreadyAdded':"Du hesch versuecht dää Layer in d Charte yyzfiege: ${layerName}, aber är isch schoi yygfiegt",'reprojectDeprecated':"Du bruchsch d \'reproject\'-Option bim ${layerName}-Layer. Die Option isch nimi giltig: si isch aagleit wore go   Date iber kommerziälli Grundcharte lege, aber des sott mer jetz mache mit dr Unterstitzig vu Spherical Mercator. Meh Informatione git s uf http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Die Methode isch veraltet un wird us dr Version 3.0 usegnuu. Bitte verwäbnd statt däm ${newMethod}.",'boundsAddError':"Du muesch e x-Wärt un e y-Wärt yygee bi dr Zuefieg-Funktion",'lonlatAddError':"Du meusch e Lengi- un e Breiti-Grad yygee bi dr Zuefieg-Funktion.",'pixelAddError':"Du muesch x- un y-Wärt aagee bi dr Zuefieg-Funktion.",'unsupportedGeometryType':"Nit unterstitze Geometrii-Typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition fählgschlaa: Elemänt mit ID ${elemId} isch villicht falsch gsetzt.",'filterEvaluateNotImplemented':"evaluiere isch nit implemäntiert in däm Filtertyp."});OpenLayers.Lang["hr"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nepodržani zahtjev ${statusText}",'permalink':"Permalink",'overlays':"Overlays",'baseLayer':"Osnovna karta",'sameProjection':"Pregledna karta radi jedino kao je u istoj projekciji kao i glava karta",'readNotImplemented':"Čitanje nije implementirano.",'writeNotImplemented':"Pisanje nije implementirano.",'noFID':"Ne mogu ažurirati značajku za koju ne postoji FID.",'errorLoadingGML':"Greška u učitavanju GML datoteke ${url}",'browserNotSupported':"Vaš preglednik ne podržava vektorsko renderiranje. Trenutno podržani rendereri su: ${renderers}",'componentShouldBe':"addFeatures : komponenta bi trebala biti ${geomType}",'getFeatureError':"getFeatureFromEvent je pozvao Layer bez renderera. Ovo obično znači da ste uništiili Layer, a ne neki Handler koji je povezan s njim.",'commitSuccess':"WFS Transakcija: USPJEŠNA ${response}",'commitFailed':"WFS Transakcija: NEUSPJEŠNA ${response}",'scale':"Mjerilo = 1 : ${scaleDenom}",'layerAlreadyAdded':"Pokušali ste dodati layer:  ${layerName} na kartu, ali je već dodan",'methodDeprecated':"Ova metoda nije odobrena i biti će maknuta u 3.0. Koristite ${newMethod}.",'boundsAddError':"Morate dati obje vrijednosti ,  x i y  da bi dodali funkciju.",'lonlatAddError':"Morate dati obje vrijednosti , (lon i lat) da bi dodali funkciju.",'pixelAddError':"Morate dati obje vrijednosti ,  x i y  da bi dodali funkciju.",'unsupportedGeometryType':"Nepodržani tip geometrije: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition nije uspjelo: element sa id ${elemId} može biti krivo smješten."});OpenLayers.Lang["hsb"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Wotmołwa njewobdźěłaneho naprašowanja ${statusText}",'permalink':"Trajny wotkaz",'overlays':"Naworštowanja",'baseLayer':"Zakładna runina",'sameProjection':"Přehladowa karta jenož funguje, hdyž je w samsnej projekciji kaž hłowna karta",'readNotImplemented':"Čitanje njeimplementowane.",'writeNotImplemented':"Pisanje njeimplementowane.",'noFID':"Funkcija, za kotruž FID njeje, njeda so aktualizować.",'errorLoadingGML':"Zmylk při začitowanju dataje ${url}",'browserNotSupported':"Twój wobhladowak wektorowe rysowanje njepodpěruje. Tuchwilu podpěrowane rysowaki su:\n${renderers}",'componentShouldBe':"addFeatures: komponenta měła ${geomType} być",'getFeatureError':"getFeatureFromEvent bu na woršće bjez rysowak zawołany. To zwjetša woznamjenja, zo sy worštu zničił, ale nic wobdźěłak, kotryž je z njej zwjazany.",'minZoomLevelError':"Kajkosć minZoomLevel je jenož za wužiwanje z worštami myslena, kotrež wot FixedZoomLevels pochadźeja. Zo tuta woršta wfs za minZoomLevel přepruwuje, je relikt zańdźenosće. Njemóžemy wšak ju wotstronić, bjeztoho zo aplikacije, kotrež na OpenLayers bazěruja a snano tutu kajkosć wužiwaja, hižo njefunguja. Tohodla smy ju jako zestarjenu woznamjenili -- přepruwowanje za minZoomLevel budu so we wersiji 3.0 wotstronjeć. Prošu wužij město toho nastajenje min/max, kaž je tu wopisane: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS-Transakcija: WUSPĚŠNA ${response}",'commitFailed':"WFS-Transakcija: NJEPORADŹENA ${response}",'googleWarning':"Woršta Google njemóžeše so korektnje začitać.\x3cbr\x3e\x3cbr\x3eZo by tutu zdźělenku wotbył, wubjer nowy BaseLayer z wuběra worštow horjeka naprawo.\x3cbr\x3e\x3cbr\x3eNajskerje so to stawa, dokelž skript biblioteki Google Maps pak njebu zapřijaty pak njewobsahuje korektny kluč API za twoje sydło.\x3cbr\x3e\x3cbr\x3eWuwiwarjo: Za pomoc ke korektnemu fungowanju worštow\n\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3etu kliknyć\x3c/a\x3e",'getLayerWarning':"Woršta ${layerType} njemóžeše so korektnje začitać.\x3cbr\x3e\x3cbr\x3eZo by tutu zdźělenku wotbył, wubjer nowy BaseLayer z wuběra worštow horjeka naprawo.\x3cbr\x3e\x3cbr\x3eNajskerje so to stawa, dokelž skript biblioteki ${layerLib} njebu korektnje zapřijaty.\x3cbr\x3e\x3cbr\x3eWuwiwarjo: Za pomoc ke korektnemu fungowanju worštow\n\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3etu kliknyć\x3c/a\x3e",'scale':"Měritko = 1 : ${scaleDenom}",'W':"Z",'E':"W",'N':"S",'S':"J",'layerAlreadyAdded':"Sy spytał runinu ${layerName} karće dodać, ale je so hižo dodała",'reprojectDeprecated':"Wužiwaš opciju \"reproject\" wořšty ${layerName}. Tuta opcija je zestarjena: jeje wužiwanje bě myslene, zo by zwobraznjenje datow nad komercielnymi bazowymi kartami podpěrało, ale funkcionalnosć měła so nětko z pomocu Sperical Mercator docpěć. Dalše informacije steja na http://trac.openlayers.org/wiki/SphericalMercator k dispoziciji.",'methodDeprecated':"Tuta metoda je so njeschwaliła a budźe so w 3.0 wotstronjeć. Prošu wužij ${newMethod} město toho.",'boundsAddError':"Dyrbiš hódnotu x kaž tež y funkciji \"add\" přepodać.",'lonlatAddError':"Dyrbiš hódnotu lon kaž tež lat funkciji \"add\" přepodać.",'pixelAddError':"Dyrbiš hódnotu x kaž tež y funkciji \"add\" přepodać.",'unsupportedGeometryType':"Njepodpěrowany geometrijowy typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition je so njeporadźił: element z id ${elemId} bu snano wopak zaměstnjeny.",'filterEvaluateNotImplemented':"wuhódnoćenje njeje za tutón filtrowy typ implementowany."});OpenLayers.Lang["hu"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nem kezelt kérés visszatérése ${statusText}",'permalink':"Permalink",'overlays':"Rávetítések",'baseLayer':"Alapréteg",'sameProjection':"Az áttekintő térkép csak abban az esetben működik, ha ugyanazon a vetületen van, mint a fő térkép.",'readNotImplemented':"Olvasás nincs végrehajtva.",'writeNotImplemented':"Írás nincs végrehajtva.",'noFID':"Nem frissíthető olyan jellemző, amely nem rendelkezik FID-del.",'errorLoadingGML':"Hiba GML-fájl betöltésekor ${url}",'browserNotSupported':"A böngészője nem támogatja a vektoros renderelést. A jelenleg támogatott renderelők:\n${renderers}",'componentShouldBe':"addFeatures : az összetevőnek ilyen típusúnak kell lennie: ${geomType}",'getFeatureError':"getFeatureFromEvent réteget hívott meg renderelő nélkül. Ez rendszerint azt jelenti, hogy megsemmisített egy fóliát, de néhány ahhoz társított kezelőt nem.",'minZoomLevelError':"A minZoomLevel tulajdonságot csak a következővel való használatra szánták: FixedZoomLevels-leszármazott fóliák. Ez azt jelenti, hogy a minZoomLevel wfs fólia jelölőnégyzetei már a múlté. Mi azonban nem távolíthatjuk el annak a veszélye nélkül, hogy az esetlegesen ettől függő OL alapú alkalmazásokat tönkretennénk. Ezért ezt érvénytelenítjük -- a minZoomLevel az alul levő jelölőnégyzet a 3.0-s verzióból el lesz távolítva. Kérjük, helyette használja a  min/max felbontás beállítást, amelyről az alábbi helyen talál leírást: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS tranzakció: SIKERES ${response}",'commitFailed':"WFS tranzakció: SIKERTELEN ${response}",'googleWarning':"A Google fólia betöltése sikertelen.\x3cbr\x3e\x3cbr\x3eAhhoz, hogy ez az üzenet eltűnjön, válasszon egy új BaseLayer fóliát a jobb felső sarokban található fóliakapcsoló segítségével.\x3cbr\x3e\x3cbr\x3eNagy valószínűséggel ez azért van, mert a Google Maps könyvtár parancsfájlja nem található, vagy nem tartalmazza az Ön oldalához tartozó megfelelő API-kulcsot.\x3cbr\x3e\x3cbr\x3eFejlesztőknek: A helyes működtetésre vonatkozó segítség az alábbi helyen érhető el, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3ekattintson ide\x3c/a\x3e",'getLayerWarning':"A(z) ${layerType} fólia nem töltődött be helyesen.\x3cbr\x3e\x3cbr\x3eAhhoz, hogy ez az üzenet eltűnjön, válasszon egy új BaseLayer fóliát a jobb felső sarokban található fóliakapcsoló segítségével.\x3cbr\x3e\x3cbr\x3eNagy valószínűséggel ez azért van, mert a(z) ${layerLib} könyvtár parancsfájlja helytelen.\x3cbr\x3e\x3cbr\x3eFejlesztőknek: A helyes működtetésre vonatkozó segítség az alábbi helyen érhető el, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3ekattintson ide\x3c/a\x3e",'scale':"Lépték = 1 : ${scaleDenom}",'W':"Ny",'E':"K",'N':"É",'S':"D",'layerAlreadyAdded':"Megpróbálta hozzáadni a(z) ${layerName} fóliát a térképhez, de az már hozzá van adva",'reprojectDeprecated':"Ön a \'reproject\' beállítást használja a(z) ${layerName} fólián. Ez a beállítás érvénytelen: használata az üzleti alaptérképek fölötti adatok megjelenítésének támogatására szolgált, de ezt a funkció ezentúl a Gömbi Mercator használatával érhető el. További információ az alábbi helyen érhető el: http://trac.openlayers.org/wiki/SphericalMercator",'methodDeprecated':"Ez a módszer érvénytelenítve lett és a 3.0-s verzióból el lesz távolítva. Használja a(z) ${newMethod} módszert helyette.",'boundsAddError':"Az x és y értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'lonlatAddError':"A hossz. és szél. értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'pixelAddError':"Az x és y értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'unsupportedGeometryType':"Nem támogatott geometriatípus: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition sikertelen: lehetséges, hogy a(z) ${elemId} azonosítójú elem téves helyre került.",'filterEvaluateNotImplemented':"ennél a szűrőtípusnál kiértékelés nem hajtódik végre."});OpenLayers.Lang["ia"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Le responsa a un requesta non esseva maneate: ${statusText}",'permalink':"Permaligamine",'overlays':"Superpositiones",'baseLayer':"Strato de base",'sameProjection':"Le mini-carta functiona solmente si illo es in le mesme projection que le carta principal",'readNotImplemented':"Lectura non implementate.",'writeNotImplemented':"Scriptura non implementate.",'noFID':"Non pote actualisar un elemento sin FID.",'errorLoadingGML':"Error al cargamento del file GML ${url}",'browserNotSupported':"Tu navigator non supporta le rendition de vectores. Le renditores actualmente supportate es:\n${renderers}",'componentShouldBe':"addFeatures: le componente debe esser del typo ${geomType}",'getFeatureError':"getFeatureFromEvent ha essite appellate in un strato sin renditor. Isto significa generalmente que tu ha destruite un strato, ma lassava un gestor associate con illo.",'minZoomLevelError':"Le proprietate minZoomLevel es solmente pro uso con le stratos descendente de FixedZoomLevels. Le facto que iste strato WFS verifica minZoomLevel es un reliquia del passato. Nonobstante, si nos lo remove immediatemente, nos pote rumper applicationes a base de OL que depende de illo. Ergo nos lo declara obsolete; le verification de minZoomLevel in basso essera removite in version 3.0. Per favor usa in su loco le configuration de resolutiones min/max como describite a: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transaction WFS: SUCCESSO ${response}",'commitFailed':"Transaction WFS: FALLEVA ${response}",'googleWarning':"Le strato Google non poteva esser cargate correctemente.\x3cbr\x3e\x3cbr\x3ePro disfacer te de iste message, selige un nove BaseLayer in le selector de strato in alto a dextra.\x3cbr\x3e\x3cbr\x3eMulto probabilemente, isto es proque le script del libreria de Google Maps non esseva includite o non contine le clave API correcte pro tu sito.\x3cbr\x3e\x3cbr\x3eDisveloppatores: Pro adjuta de corriger isto, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclicca hic\x3c/a",'getLayerWarning':"Le strato ${layerType} non poteva esser cargate correctemente.\x3cbr\x3e\x3cbr\x3ePro disfacer te de iste message, selige un nove BaseLayer in le selector de strato in alto a dextra.\x3cbr\x3e\x3cbr\x3eMulto probabilemente, isto es proque le script del libreria de ${layerLib} non esseva correctemente includite.\x3cbr\x3e\x3cbr\x3eDisveloppatores: Pro adjuta de corriger isto, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclicca hic\x3c/a\x3e",'scale':"Scala = 1 : ${scaleDenom}",'W':"W",'E':"E",'N':"N",'S':"S",'layerAlreadyAdded':"Tu tentava adder le strato: ${layerName} al carta, ma illo es ja presente",'reprojectDeprecated':"Tu usa le option \'reproject\' in le strato ${layerName} layer. Iste option es obsolescente: illo esseva pro poter monstrar datos super cartas de base commercial, ma iste functionalitate pote ora esser attingite con le uso de Spherical Mercator. Ulterior information es disponibile a http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Iste methodo ha essite declarate obsolescente e essera removite in version 3.0. Per favor usa ${newMethod} in su loco.",'boundsAddError':"Tu debe passar le duo valores x e y al function add.",'lonlatAddError':"Tu debe passar le duo valores lon e lat al function add.",'pixelAddError':"Tu debe passar le duo valores x e y al function add.",'unsupportedGeometryType':"Typo de geometria non supportate: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition falleva: le elemento con id ${elemId} pote esser mal placiate.",'filterEvaluateNotImplemented':"\"evaluate\" non es implementate pro iste typo de filtro."});OpenLayers.Lang["id"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Permintaan yang tak tertangani menghasilkan ${statusText}",'permalink':"Pranala permanen",'overlays':"Hamparan",'baseLayer':"Lapisan Dasar",'sameProjection':"Peta tinjauan hanya bekerja bila dalam proyeksi yang sama dengan peta utama",'readNotImplemented':"Membaca tidak diterapkan.",'writeNotImplemented':"Menyimpan tidak diterapkan.",'noFID':"Tidak dapat memperbarui fitur yang tidak memiliki FID.",'errorLoadingGML':"Kesalahan dalam memuat berkas GML ${url}",'browserNotSupported':"Peramban Anda tidak mendukung penggambaran vektor. Penggambar yang didukung saat ini adalah:\n${renderers}",'componentShouldBe':"addFeatures : komponen harus berupa ${geomType}",'getFeatureError':"getFeatureFromEvent diterapkan pada lapisan tanpa penggambar. Ini biasanya berarti Anda menghapus sebuah lapisan, tetapi tidak menghapus penangan yang terkait dengannya.",'minZoomLevelError':"Properti minZoomLevel hanya ditujukan bekerja dengan lapisan FixedZoomLevels-descendent. Pengecekan minZoomLevel oleh lapisan wfs adalah peninggalan masa lalu. Kami tidak dapat menghapusnya tanpa kemungkinan merusak aplikasi berbasis OL yang mungkin bergantung padanya. Karenanya, kami menganggapnya tidak berlaku -- Cek minZoomLevel di bawah ini akan dihapus pada 3.0. Silakan gunakan penyetelan resolusi min/maks seperti dijabarkan di sini: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS Transaksi: BERHASIL ${respon}",'commitFailed':"WFS Transaksi: GAGAL ${respon}",'googleWarning':"Lapisan Google tidak dapat dimuat dengan benar.\x3cbr\x3e\x3cbr\x3eUntuk menghilangkan pesan ini, pilih suatu BaseLayer baru melalui penukar lapisan (layer switcher) di ujung kanan atas.\x3cbr\x3e\x3cbr\x3eKemungkinan besar ini karena pustaka skrip Google Maps tidak disertakan atau tidak mengandung kunci API yang tepat untuk situs Anda.\x3cbr\x3e\x3cbr\x3ePengembang: Untuk bantuan mengatasi masalah ini, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eklik di sini\x3c/a\x3e",'getLayerWarning':"Lapisan ${layerType} tidak dapat dimuat dengan benar.\x3cbr\x3e\x3cbr\x3eUntuk menghilangkan pesan ini, pilih suatu BaseLayer baru melalui penukar lapisan (layer switcher) di ujung kanan atas.\x3cbr\x3e\x3cbr\x3eKemungkinan besar ini karena pustaka skrip Google Maps tidak disertakan dengan benar.\x3cbr\x3e\x3cbr\x3ePengembang: Untuk bantuan mengatasi masalah ini, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eklik di sini\x3c/a\x3e",'scale':"Sekala = 1 : ${scaleDenom}",'W':"B",'E':"T",'N':"U",'S':"S",'layerAlreadyAdded':"Anda mencoba menambahkan lapisan: ${layerName} ke dalam peta, tapi lapisan itu telah ditambahkan",'reprojectDeprecated':"Anda menggunakan opsi \'reproject\' pada lapisan ${layerName}. Opsi ini telah ditinggalkan: penggunaannya dirancang untuk mendukung tampilan data melalui peta dasar komersial, tapi fungsionalitas tersebut saat ini harus dilakukan dengan menggunakan dukungan Spherical Mercator. Informasi lebih lanjut tersedia di http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Metode ini telah usang dan akan dihapus di 3.0. Sebaliknya, harap gunakan ${newMethod}.",'boundsAddError':"Anda harus memberikan kedua nilai x dan y ke fungsi penambah.",'lonlatAddError':"Anda harus memberikan kedua nilai lon dan lat ke fungsi penambah.",'pixelAddError':"Anda harus memberikan kedua nilai x dan y ke fungsi penambah.",'unsupportedGeometryType':"Tipe geometri tak didukung: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition gagal: elemen dengan id ${elemId} mungkin salah tempat.",'filterEvaluateNotImplemented':"evaluasi tidak tersedia untuk tipe filter ini."});OpenLayers.Lang["io"]=OpenLayers.Util.applyDefaults({'scale':"Skalo = 1 : ${scaleDenom}"});OpenLayers.Lang["is"]=OpenLayers.Util.applyDefaults({'permalink':"Varanlegur tengill",'overlays':"Þekjur",'baseLayer':"Grunnlag",'sameProjection':"Yfirlitskortið virkar aðeins ef það er í sömu vörpun og aðalkortið",'readNotImplemented':"Skrifun er óútfærð.",'writeNotImplemented':"Lestur er óútfærður.",'errorLoadingGML':"Villa kom upp við að hlaða inn GML skránni ${url}",'scale':"Skali = 1 : ${scaleDenom}",'layerAlreadyAdded':"Þú reyndir að bæta laginu ${layerName} á kortið en það er þegar búið að bæta því við",'methodDeprecated':"Þetta fall hefur verið úrelt og verður fjarlægt í 3.0. Notaðu ${newMethod} í staðin."});OpenLayers.Lang["ja"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"未処理の要求は ${statusText} を返します",'permalink':"パーマリンク",'overlays':"オーバーレイ",'baseLayer':"基底レイヤー",'sameProjection':"概観地図はメインの地図と同じ投影法をとる場合のみ機能します",'readNotImplemented':"読み込みは実装されていません。",'writeNotImplemented':"書き込みは実装されていません。",'noFID':"FID のない地物は更新できません。",'errorLoadingGML':"GML ファイル ${url} の読み込みエラー",'browserNotSupported':"あなたのブラウザはベクターグラフィックスの描写に対応していません。現時点で対応しているソフトウェアは以下のものです。\n${renderers}",'componentShouldBe':"addFeatures: 要素は ${geomType} であるべきです",'getFeatureError':"getFeatureFromEvent がレンダラーのないレイヤーから呼ばれました。通常、これはあなたがレイヤーを、それに関連づけられたいくつかのハンドラを除いて、破壊してしまったことを意味します。",'minZoomLevelError':"minZoomLevel プロパティは FixedZoomLevels を継承するレイヤーでの使用のみを想定しています。この minZoomLevel に対する WFS レイヤーの検査は歴史的なものです。しかしながら、この検査を除去するとそれに依存する OpenLayers ベースのアプリケーションを破壊してしまう可能性があります。よって廃止が予定されており、この minZoomLevel 検査はバージョン3.0で除去されます。代わりに、http://trac.openlayers.org/wiki/SettingZoomLevels で解説されている、最小および最大解像度設定を使用してください。",'commitSuccess':"WFS トランザクション: 成功 ${response}",'commitFailed':"WFS トランザクション: 失敗 ${response}",'googleWarning':"Google レイヤーが正しく読み込みを行えませんでした。\x3cbr\x3e\x3cbr\x3eこのメッセージを消すには、右上の隅にあるレイヤー切り替え部分で新しい基底レイヤーを選んでください。\x3cbr\x3e\x3cbr\x3eおそらく、これは Google マップ用ライブラリのスクリプトが組み込まれていないか、あなたのサイトに対応する正しい API キーが設定されていないためです。\x3cbr\x3e\x3cbr\x3e開発者の方へ: 正しい動作をさせるために\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eこちらのウィキ\x3c/a\x3eを参照してください。",'getLayerWarning':"${layerType} レイヤーが正しく読み込みを行えませんでした。\x3cbr\x3e\x3cbr\x3eこのメッセージを消すには、右上の隅にあるレイヤー切り替え部分で新しい基底レイヤーを選んでください。\x3cbr\x3e\x3cbr\x3eおそらく、これは ${layerLib} ライブラリのスクリプトが正しく組み込まれていないためです。\x3cbr\x3e\x3cbr\x3e開発者の方へ: 正しい動作をさせるために\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eこちらのウィキ\x3c/a\x3eを参照してください。",'scale':"縮尺 = 1 : ${scaleDenom}",'W':"西",'E':"東",'N':"北",'S':"南",'layerAlreadyAdded':"あなたは「${layerName}」を地図に追加しようと試みましたが、そのレイヤーは既に追加されています",'reprojectDeprecated':"あなたは「${layerName}」レイヤーで reproject オプションを使っています。このオプションは商用の基底地図上に情報を表示する目的で設計されましたが、現在ではその機能は Spherical Mercator サポートを利用して実現されており、このオプションの使用は非推奨です。追加の情報は http://trac.openlayers.org/wiki/SphericalMercator で入手できます。",'methodDeprecated':"このメソッドは廃止が予定されており、バージョン3.0で除去されます。代わりに ${newMethod} を使用してください。",'boundsAddError':"x と y 両方の値を add 関数に渡さなければなりません。",'lonlatAddError':"lon と lat 両方の値を add 関数に渡さなければなりません。",'pixelAddError':"x と y の値両方を add 関数に渡さなければなりません。",'unsupportedGeometryType':"未対応の形状型: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition が失敗しました: id ${elemId} をもつ要素が誤った位置にある可能性があります。",'filterEvaluateNotImplemented':"このフィルター型について evaluate は実装されていません。"});OpenLayers.Lang["km"]=OpenLayers.Util.applyDefaults({'permalink':"តំណភ្ជាប់អចិន្ត្រៃយ៍",'baseLayer':"ស្រទាប់បាត​",'errorLoadingGML':"កំហុសកំឡុងពេលផ្ទុកឯកសារ GML ${url}",'scale':"មាត្រដ្ឋាន = ១ ៖ ${scaleDenom}"});OpenLayers.Lang["ksh"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Met dä Antwoot op en Aanfrooch ham_mer nix aanjefange: ${statusText}",'permalink':"Lengk op Duuer",'overlays':"Drövver jelaat",'baseLayer':"Jrund-Nivoh",'sameProjection':"De Övverseeschs_Kaat deiht et bloß, wann se de sälve Projäxjuhn bruche deiht, wi de Houp_Kaat",'readNotImplemented':"„\x3ccode lang=\"en\"\x3eread\x3c/code\x3e“ is em Projramm nit fürjesinn.",'writeNotImplemented':"„\x3ccode lang=\"en\"\x3ewrite\x3c/code\x3e“ is em Projramm nit fürjesinn.",'noFID':"En Saach, woh kein \x3ci lang=\"en\"\x3eFID\x3c/i\x3e för doh es, löht sesch nit ändere.",'errorLoadingGML':"Fähler beim \x3ci lang=\"en\"\x3eGML\x3c/i\x3e-Datei-Laade vun \x3ccode\x3e${url}\x3c/code\x3e",'browserNotSupported':"Dinge Brauser kann kein Väktore ußjävve. De Zoote Ußjaabe, di em Momang jon, sen:\n${renderers}",'componentShouldBe':"\x3ccode lang=\"en\"\x3eaddFeatures\x3c/code\x3e: dä Aandeil sullt vun dä Zoot „\x3ccode lang=\"en\"\x3e${geomType}\x3c/code\x3e“ sin.",'getFeatureError':"\x3ccode lang=\"en\"\x3egetFeatureFromEvent\x3c/code\x3e es vun enem Nivoh opjeroofe woode, woh et kei Projramm zom Ußjävve jit. Dat bedügg för jewöhnlesch, dat De e Nivoh kapott jemaat häs, ävver nit e Projramm för domet ömzejonn, wat domet verbonge es.",'minZoomLevelError':"De Eijeschaff „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“ es bloß doför jedaach, dat mer se met dä Nivvohß bruch, di vun \x3ccode lang=\"en\"\x3eFixedZoomLevels\x3c/code\x3e affhange don. Dat dat \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Nivvoh övverhoup de Eijeschaff „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“ pröhfe deiht, es noch övveresch vun fröhjer. Mer künne dat ävver jez nit fott lohße, oohne dat mer Jevaa loufe, dat Aanwendunge vun OpenLayers nit mieh loufe, di sesch doh velleijsch noch drop am verlohße sin. Dröm sare mer, dat mer et nit mieh han welle, un de „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“-Eijeschaff weed hee vun de Version 3.0 af nit mieh jeprööf wäde. Nemm doför de Enstellung för de hühßte un de kleinßte Oplöhsung, esu wi et en http://trac.openlayers.org/wiki/SettingZoomLevels opjeschrevve es.",'commitSuccess':"Dä \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Vörjang es joot jeloufe: ${response}",'commitFailed':"Dä \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Vörjang es scheif jejange: ${response}",'googleWarning':"Dat Nivvoh \x3ccode lang=\"en\"\x3eGoogle\x3c/code\x3e kunnt nit reschtesch jelaade wääde.\x3cbr /\x3e\x3cbr /\x3eÖm hee di Nohreesch loß ze krijje, donn en ander Jrund-Nivvoh ußsöhke, rähß bovve en de Äk.\x3cbr /\x3e\x3cbr /\x3eWascheinlesch es dat wiel dat \x3ci lang=\"en\"\x3eGoogle-Maps\x3c/i\x3e-Skrepp entweeder nit reschtesch enjebonge wood, udder nit dä reschtejje \x3ci lang=\"en\"\x3eAPI\x3c/i\x3e-Schlößel för Ding Web-ßait scheke deiht.\x3cbr /\x3e\x3cbr /\x3eFör Projrammierer jidd_et Hölp do_drövver, \x3ca href=\"http://trac.openlayers.org/wiki/Google\" target=\"_blank\"\x3ewi mer dat aan et Loufe brengk\x3c/a\x3e.",'getLayerWarning':"Dat Nivvoh \x3ccode\x3e${layerType}\x3c/code\x3e kunnt nit reschtesch jelaade wääde.\x3cbr /\x3e\x3cbr /\x3eÖm hee di Nohreesch loß ze krijje, donn en ander Jrund-Nivvoh ußsöhkre, rähß bovve en de Äk.\x3cbr /\x3e\x3cbr /\x3eWascheinlesch es dat, wiel dat Skrepp \x3ccode\x3e${layerLib}\x3c/code\x3e nit reschtesch enjebonge wood.\x3cbr /\x3e\x3cbr /\x3eFör Projrammierer jidd_Et Hölp do_drövver, \x3ca href=\"http://trac.openlayers.org/wiki/${layerLib}\" target=\"_blank\"\x3ewi mer dat aan et Loufe brengk\x3c/a\x3e.",'scale':"Mohßshtaab = 1 : ${scaleDenom}",'W':"W",'E':"O",'N':"N",'S':"S",'layerAlreadyAdded':"Do häß versöhk, dat Nivvoh \x3ccode\x3e${layerName}\x3c/code\x3e en di Kaat eren ze bränge, et wohr ävver ald do dren.",'reprojectDeprecated':"Do bruchs de Ußwahl \x3ccode\x3ereproject\x3c/code\x3e op däm Nivvoh \x3ccode\x3e${layerName}\x3c/code\x3e. Di Ußwahl es nit mieh jähn jesinn. Se wohr doför jedaach, öm Date op jeschääfsmäßesch eruß jejovve Kaate bovve drop ze moole, wat ävver enzwesche besser met dä Öngershtözung för de ßfääresche Mäkaator Beldscher jeiht. Doh kanns De mieh drövver fenge op dä Sigg: http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Hee di Metood es nim_mih aktoäll un et weed se en dä Version 3.0 nit mieh jävve. Nemm \x3ccode\x3e${newMethod}\x3c/code\x3e doföör.",'boundsAddError':"Do moß beeds vun de \x3ccode\x3ex\x3c/code\x3e un \x3ccode\x3ey\x3c/code\x3e Wääte aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'lonlatAddError':"Do moß beeds \x3ccode\x3elon\x3c/code\x3e un \x3ccode\x3elat\x3c/code\x3e aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'pixelAddError':"Do moß beeds \x3ccode\x3ex\x3c/code\x3e un \x3ccode\x3ey\x3c/code\x3e aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'unsupportedGeometryType':"De Zoot Jommetrii dom_mer nit ongershtöze: \x3ccode\x3e${geomType}\x3c/code\x3e",'pagePositionFailed':"\x3ccode lang=\"en\"\x3eOpenLayers.Util.pagePosition\x3c/code\x3e es donevve jejange: dat Denge met dä Kännong \x3ccode\x3e${elemId}\x3c/code\x3e künnt am verkeehte Plaz sin.",'filterEvaluateNotImplemented':"„\x3ccode lang=\"en\"\x3eevaluate\x3c/code\x3e“ es för di Zoot Fellter nit enjereschdt."});OpenLayers.Lang["nds"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Unbehannelt Trüchmellels för de Anfraag ${statusText}",'permalink':"Permalink",'overlays':"Overlays",'baseLayer':"Achtergrundkoort",'sameProjection':"De Översichtskoort geiht blot, wenn de sülve Projekschoon as bi de Hööftkoort bruukt warrt",'readNotImplemented':"Lesen is nich inricht.",'writeNotImplemented':"Schrieven is nich inricht.",'noFID':"En Feature, dat keen FID hett, kann nich aktuell maakt warrn.",'errorLoadingGML':"Fehler bi’t Laden vun de GML-Datei ${url}",'browserNotSupported':"Dien Browser ünnerstütt keen Vektorbiller. Ünnerstütt Renderers:\n${renderers}",'componentShouldBe':"addFeatures : Kumponent schull man den Typ ${geomType} hebben",'getFeatureError':"getFeatureFromEvent is von en Laag ahn Render opropen worrn. Dat bedüüdt normalerwies, dat en Laag wegmaakt worrn is, aver nich de Handler, de dor op verwiest.",'commitSuccess':"WFS-Transakschoon: hett klappt ${response}",'commitFailed':"WFS-Transakschoon: hett nich klappt ${response}",'scale':"Skaal = 1 : ${scaleDenom}",'layerAlreadyAdded':"Du versöchst de Laag „${layerName}“ to de Koort totofögen, man de is al toföögt",'methodDeprecated':"Disse Methood is oold un schall dat in 3.0 nich mehr geven. Bruuk dor man beter ${newMethod} för.",'boundsAddError':"De Weert x un y, de mööt all beid an de add-Funkschoon övergeven warrn.",'lonlatAddError':"De Weert lon un lat, de mööt all beid an de add-Funkschoon övergeven warrn.",'pixelAddError':"De Weert x un y, de mööt all beid an de add-Funkschoon övergeven warrn.",'unsupportedGeometryType':"Nich ünnerstütt Geometrie-Typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition güng nich: Element mit de Id ${elemId} is villicht an’n verkehrten Platz."});OpenLayers.Lang["nn"]=OpenLayers.Util.applyDefaults({'scale':"Skala = 1 : ${scaleDenom}",'layerAlreadyAdded':"Du freista å leggja til laget «${layerName}» på kartet, men det har alt vorte lagt til.",'boundsAddError':"Du er nøydd til å gje både ein x- og ein y-verdi til «add»-funksjonen.",'lonlatAddError':"Du er nøydd til å gje både lon- og lat-verdiar til «add»-funksjonen.",'pixelAddError':"Du er nøydd til å gje både ein x- og ein y-verdi til «add»-funksjonen."});OpenLayers.Lang["oc"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Requèsta pas gerida, retorna ${statusText}",'permalink':"Permaligam",'overlays':"Calques",'baseLayer':"Calc de basa",'sameProjection':"La carta de situacion fonciona pas que quora sa projeccion es la meteissa que la de la carta principala",'readNotImplemented':"Lectura pas implementada.",'writeNotImplemented':"Escritura pas implementada.",'noFID':"Impossible de metre a jorn un objècte sens identificant (fid).",'errorLoadingGML':"Error al cargament del fichièr GML ${url}",'browserNotSupported':"Vòstre navegidor supòrta pas lo rendut vectorial. Los renderers actualament suportats son : \n${renderers}",'componentShouldBe':"addFeatures : lo compausant deuriá èsser de tipe ${geomType}",'getFeatureError':"getFeatureFromEvent es estat apelat sus un calc sens renderer. Aquò significa generalament qu\'avètz destruch aqueste jaç, mas qu\'avètz conservat un handler que li èra associat.",'minZoomLevelError':"La proprietat minZoomLevel deu èsser utilizada solament per de jaces FixedZoomLevels-descendent. Lo fach qu\'aqueste jaç WFS verifique la preséncia de minZoomLevel es una relica del passat. Çaquelà, la podèm suprimir sens copar d\'aplicacions que ne poirián dependre. Es per aquò que la depreciam -- la verificacion del minZoomLevel serà suprimida en version 3.0. A la plaça, mercés d\'utilizar los paramètres de resolucions min/max tal coma descrich sus : http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transaccion WFS : SUCCES ${response}",'commitFailed':"Transaccion WFS : FRACAS ${response}",'googleWarning':"Lo jaç Google es pas estat en mesura de se cargar corrèctament.\x3cbr\x3e\x3cbr\x3ePer suprimir aqueste messatge, causissètz una BaseLayer novèla dins lo selector de jaç en naut a drecha.\x3cbr\x3e\x3cbr\x3eAquò es possiblament causat par la non-inclusion de la librariá Google Maps, o alara perque que la clau de l\'API correspond pas a vòstre site.\x3cbr\x3e\x3cbr\x3eDesvolopaires : per saber cossí corregir aquò, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclicatz aicí\x3c/a\x3e",'getLayerWarning':"Lo jaç ${layerType} es pas en mesura de se cargar corrèctament.\x3cbr\x3e\x3cbr\x3ePer suprimir aqueste messatge, causissètz una  BaseLayer novèla dins lo selector de jaç en naut a drecha.\x3cbr\x3e\x3cbr\x3eAquò es possiblament causat per la non-inclusion de la librariá ${layerLib}.\x3cbr\x3e\x3cbr\x3eDesvolopaires : per saber cossí corregir aquí, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclicatz aicí\x3c/a\x3e",'scale':"Escala ~ 1 : ${scaleDenom}",'W':"O",'E':"È",'N':"N",'S':"S",'layerAlreadyAdded':"Avètz ensajat d\'apondre a la carta lo calc : ${layerName}, mas ja es present",'reprojectDeprecated':"Utilizatz l\'opcion \'reproject\' sul jaç ${layerName}. Aquesta opcion es despreciada : Son usatge permetiá d\'afichar de donadas al dessús de jaces raster comercials. Aquesta foncionalitat ara es suportada en utilizant lo supòrt de la projeccion Mercator Esferica. Mai d\'informacion es disponibla sus http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Aqueste metòde es despreciada, e serà suprimida a la version 3.0. Mercés d\'utilizar ${newMethod} a la plaça.",'boundsAddError':"Vos cal passar las doas valors x e y a la foncion add.",'lonlatAddError':"Vos cal passar las doas valors lon e lat a la foncion add.",'pixelAddError':"Vos cal passar las doas valors x e y a la foncion add.",'unsupportedGeometryType':"Tipe de geometria pas suportat : ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition a fracassat : l\'element d\'id ${elemId} poiriá èsser mal posicionat.",'filterEvaluateNotImplemented':"evaluar es pas encara estat implementat per aqueste tipe de filtre."});OpenLayers.Lang["pt"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Servidor devolveu erro não contemplado ${statusText}",'permalink':"Ligação permanente",'overlays':"Sobreposições",'baseLayer':"Camada Base",'sameProjection':"O mapa panorâmico só funciona quando está na mesma projeção que o mapa principal",'readNotImplemented':"Leitura não implementada.",'writeNotImplemented':"Escrita não implementada.",'noFID':"Não é possível atualizar um elemento para a qual não há FID.",'errorLoadingGML':"Erro ao carregar ficheiro GML ${url}",'browserNotSupported':"O seu navegador não suporta renderização vetorial. Actualmente os renderizadores suportados são:\n${renderers}",'componentShouldBe':"addFeatures: componente deve ser um(a) ${geomType}",'getFeatureError':"getFeatureFromEvent foi chamado numa camada sem renderizador. Isto normalmente significa que destruiu uma camada, mas não um manipulador \'\'(handler)\'\' que lhe está associado.",'minZoomLevelError':"A propriedade minZoomLevel só deve ser usada com as camadas descendentes da FixedZoomLevels. A verificação da propriedade por esta camada wfs é uma relíquia do passado. No entanto, não podemos removê-la sem correr o risco de afectar aplicações OL que dependam dela. Portanto, estamos a torná-la obsoleta -- a verificação minZoomLevel será removida na versão 3.0. Em vez dela, por favor, use as opções de resolução min/max descritas aqui: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transacção WFS: SUCESSO ${response}",'commitFailed':"Transacção WFS: FALHOU ${response}",'googleWarning':"A Camada Google não foi correctamente carregada.\x3cbr\x3e\x3cbr\x3ePara deixar de receber esta mensagem, seleccione uma nova Camada-Base no \'\'switcher\'\' de camadas no canto superior direito.\x3cbr\x3e\x3cbr\x3eProvavelmente, isto acontece porque o \'\'script\'\' da biblioteca do Google Maps não foi incluído ou não contém a chave API correcta para o seu sítio.\x3cbr\x3e\x3cbr\x3eProgramadores: Para ajuda sobre como solucionar o problema \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclique aqui\x3c/a\x3e .",'getLayerWarning':"A camada ${layerType} não foi correctamente carregada.\x3cbr\x3e\x3cbr\x3ePara desactivar esta mensagem, seleccione uma nova Camada-Base no \'\'switcher\'\' de camadas no canto superior direito.\x3cbr\x3e\x3cbr\x3eProvavelmente, isto acontece porque o \'\'script\'\' da biblioteca ${layerLib} não foi incluído correctamente.\x3cbr\x3e\x3cbr\x3eProgramadores: Para ajuda sobre como solucionar o problema \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclique aqui\x3c/a\x3e .",'scale':"Escala = 1 : ${scaleDenom}",'W':"O",'E':"E",'N':"N",'S':"S",'layerAlreadyAdded':"Você tentou adicionar a camada: ${layerName} ao mapa, mas ela já tinha sido adicionada antes",'reprojectDeprecated':"Está usando a opção \'reproject\' na camada ${layerName}. Esta opção é obsoleta: foi concebida para permitir a apresentação de dados sobre mapas-base comerciais, mas esta funcionalidade é agora suportada pelo Mercator Esférico. Mais informação está disponível em http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Este método foi declarado obsoleto e será removido na versão 3.0. Por favor, use ${newMethod} em vez disso.",'boundsAddError':"Você deve passar tanto o valor x como o y à função de adição.",'lonlatAddError':"Você deve passar tanto o valor lon como o lat à função de adição.",'pixelAddError':"Você deve passar tanto o valor x como o y à função de adição.",'unsupportedGeometryType':"Tipo de geometria não suportado: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition falhou: o elemento com o id ${elemId} poderá estar mal-posicionado.",'filterEvaluateNotImplemented':"avaliar não está implementado para este tipo de filtro."});OpenLayers.Lang["ru"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Необработанный запрос вернул ${statusText}",'permalink':"Постоянная ссылка",'overlays':"Слои",'baseLayer':"Основной слой",'sameProjection':"Обзорная карта работает только тогда, когда имеет ту же проекцию, что и основная",'readNotImplemented':"Чтение не реализовано.",'writeNotImplemented':"Запись не реализована.",'noFID':"Невозможно обновить объект, для которого нет FID.",'errorLoadingGML':"Ошибка при загрузке файла GML ${url}",'browserNotSupported':"Ваш браузер не поддерживает векторную графику. На данный момент поддерживаются:\n${renderers}",'componentShouldBe':"addFeatures: компонент должен быть ${geomType}",'getFeatureError':"getFeatureFromEvent вызван для слоя без рендерера. Обычно это говорит о том, что вы уничтожили слой, но оставили связанный с ним обработчик.",'minZoomLevelError':"Свойство minZoomLevel предназначено только для использования со слоями, являющимися потомками FixedZoomLevels. То, что этот WFS-слой проверяется на minZoomLevel — реликт прошлого. Однако мы не можем удалить эту функцию, так как, возможно, от неё зависят некоторые основанные на OpenLayers приложения. Функция объявлена устаревшей — проверка minZoomLevel будет удалена в 3.0. Пожалуйста, используйте вместо неё настройку мин/макс разрешения, описанную здесь: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Транзакция WFS: УСПЕШНО ${response}",'commitFailed':"Транзакция WFS: ОШИБКА ${response}",'googleWarning':"Слой Google не удалось нормально загрузить.\x3cbr\x3e\x3cbr\x3eЧтобы избавиться от этого сообщения, выбите другой основной слой в переключателе в правом верхнем углу.\x3cbr\x3e\x3cbr\x3eСкорее всего, причина в том, что библиотека Google Maps не была включена или не содержит корректного API-ключа для вашего сайта.\x3cbr\x3e\x3cbr\x3eРазработчикам: чтобы узнать, как сделать, чтобы всё заработало, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eщёлкните тут\x3c/a\x3e",'getLayerWarning':"Слой ${layerType} не удалось нормально загрузить. \x3cbr\x3e\x3cbr\x3eЧтобы избавиться от этого сообщения, выбите другой основной слой в переключателе в правом верхнем углу.\x3cbr\x3e\x3cbr\x3eСкорее всего, причина в том, что библиотека ${layerLib} не была включена или была включена некорректно.\x3cbr\x3e\x3cbr\x3eРазработчикам: чтобы узнать, как сделать, чтобы всё заработало, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eщёлкните тут\x3c/a\x3e",'scale':"Масштаб = 1 : ${scaleDenom}",'W':"З",'E':"В",'N':"С",'S':"Ю",'layerAlreadyAdded':"Вы попытались добавить слой «${layerName}» на карту, но он уже был добавлен",'reprojectDeprecated':"Вы используете опцию \'reproject\' для слоя ${layerName}. Эта опция является устаревшей: ее использование предполагалось для поддержки показа данных поверх коммерческих базовых карт, но теперь этот функционал несёт встроенная поддержка сферической проекции Меркатора. Больше сведений доступно на http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Этот метод считается устаревшим и будет удалён в версии 3.0. Пожалуйста, пользуйтесь ${newMethod}.",'boundsAddError':"Функции add надо передавать оба значения, x и y.",'lonlatAddError':"Функции add надо передавать оба значения, lon и lat.",'pixelAddError':"Функции add надо передавать оба значения, x и y.",'unsupportedGeometryType':"Неподдерживаемый тип геометрии: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition failed: элемент с id ${elemId} может находиться не в нужном месте.",'filterEvaluateNotImplemented':"evaluate не реализовано для фильтра данного типа."});OpenLayers.Lang["sk"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Neobslúžené požiadavky vracajú ${statusText}",'permalink':"Trvalý odkaz",'overlays':"Prekrytia",'baseLayer':"Základná vrstva",'sameProjection':"Prehľadová mapka funguje iba vtedy, keď je v rovnakej projekcii ako hlavná mapa",'readNotImplemented':"Čítanie nie je implementované.",'writeNotImplemented':"Zápis nie je implementovaný.",'noFID':"Nie je možné aktualizovať vlastnosť, pre ktorú neexistuje FID.",'errorLoadingGML':"Chyba pri načítaní súboru GML ${url}",'browserNotSupported':"Váš prehliadač nepodporuje vykresľovanie vektorov. Momentálne podporované vykresľovače sú:\n${renderers}",'componentShouldBe':"addFeatures: komponent by mal byť ${geomType}",'getFeatureError':"getFeatureFromEvent bola zavolaná na vrstve bez vykresľovača. To zvyčajne znamená, že ste odstránili vrstvu, ale nie niektorú z obslúh, ktorá je s ňou asociovaná.",'minZoomLevelError':"Vlastnosť minZoomLevel je určený iba na použitie s vrstvami odvodenými od FixedZoomLevels. To, že táto wfs vrstva kontroluje minZoomLevel je pozostatok z minulosti. Nemôžeme ho však odstrániť, aby sme sa vyhli možnému porušeniu aplikácií založených na Open Layers, ktoré na tomto môže závisieť. Preto ho označujeme ako zavrhovaný - dolu uvedená kontrola minZoomLevel bude odstránená vo verzii 3.0. Použite prosím namiesto toho kontrolu min./max. rozlíšenia podľa tu uvedeného popisu: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transakcia WFS: ÚSPEŠNÁ ${response}",'commitFailed':"Transakcia WFS: ZLYHALA ${response}",'googleWarning':"Vrstvu Google nebolo možné správne načítať.\x3cbr\x3e\x3cbr\x3eAby ste sa tejto správy zbavili vyberte novú BaseLayer v prepínači vrstiev v pravom hornom rohu.\x3cbr\x3e\x3cbr\x3eToto sa stalo pravdepodobne preto, že skript knižnice Google Maps buď nebol načítaný alebo neobsahuje správny kľúč API pre vašu lokalitu.\x3cbr\x3e\x3cbr\x3eVývojári: Tu môžete získať \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3epomoc so sfunkčnením\x3c/a\x3e",'getLayerWarning':"Vrstvu ${layerType} nebolo možné správne načítať.\x3cbr\x3e\x3cbr\x3eAby ste sa tejto správy zbavili vyberte novú BaseLayer v prepínači vrstiev v pravom hornom rohu.\x3cbr\x3e\x3cbr\x3eToto sa stalo pravdepodobne preto, že skript knižnice ${layerType} buď nebol načítaný alebo neobsahuje správny kľúč API pre vašu lokalitu.\x3cbr\x3e\x3cbr\x3eVývojári: Tu môžete získať \x3ca href=\'http://trac.openlayers.org/wiki/${layerType}\' target=\'_blank\'\x3epomoc so sfunkčnením\x3c/a\x3e",'scale':"Mierka = 1 : ${scaleDenom}",'layerAlreadyAdded':"Pokúsili ste sa do mapy pridať vrstvu ${layerName}, ale tá už bola pridaná",'reprojectDeprecated':"Používate voľby „reproject“ vrstvy ${layerType}. Táto voľba je zzavrhovaná: jej použitie bolo navrhnuté na podporu zobrazovania údajov nad komerčnými základovými mapami, ale túto funkcionalitu je teraz možné dosiahnuť pomocou Spherical Mercator. Ďalšie informácie získate na stránke http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Táto metóda je zavrhovaná a bude odstránená vo verzii 3.0. Použite prosím namiesto nej metódu ${newMethod}.",'boundsAddError':"Sčítacej funkcii musíte dať hodnoty x aj y.",'lonlatAddError':"Sčítacej funkcii musíte dať hodnoty lon (zem. dĺžka) aj lat (zem. šírka).",'pixelAddError':"Sčítacej funkcii musíte dať hodnoty x aj y.",'unsupportedGeometryType':"Nepodporovaný typ geometrie: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition zlyhalo: prvok s id ${elemId} môže byť zle umiestnený.",'filterEvaluateNotImplemented':"evaluate nie je implementovaný pre tento typ filtra"});OpenLayers.Lang["te"]=OpenLayers.Util.applyDefaults({'permalink':"స్థిరలింకు",'W':"ప",'E':"తూ",'N':"ఉ",'S':"ద"});OpenLayers.Lang["vi"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Không xử lý được phản hồi ${statusText} cho yêu cầu",'permalink':"Liên kết thường trực",'overlays':"Lấp bản đồ",'baseLayer':"Lớp nền",'sameProjection':"Bản đồ toàn cảnh chỉ hoạt động khi cùng phép chiếu với bản đồ chính",'readNotImplemented':"Chưa hỗ trợ chức năng đọc.",'writeNotImplemented':"Chưa hỗ trợ chức năng viết.",'noFID':"Không thể cập nhật tính năng thiếu FID.",'errorLoadingGML':"Lỗi tải tập tin GML tại ${url}",'browserNotSupported':"Trình duyệt của bạn không hỗ trợ chức năng vẽ bằng vectơ. Hiện hỗ trợ các bộ kết xuất:\n${renderers}",'componentShouldBe':"addFeatures: bộ phận cần phải là ${geomType}",'getFeatureError':"getFeatureFromEvent được gọi từ lớp không có bộ kết xuất. Thường thì có lẽ lớp bị xóa nhưng một phần xử lý của nó vẫn còn.",'minZoomLevelError':"Chỉ nên sử dụng thuộc tính minZoomLevel với các lớp FixedZoomLevels-descendent. Việc lớp wfs này tìm cho minZoomLevel là di tích còn lại từ xưa. Tuy nhiên, nếu chúng tôi dời nó thì sẽ vỡ các chương trình OpenLayers mà dựa trên nó. Bởi vậy chúng tôi phản đối sử dụng nó\x26nbsp;– bước tìm cho minZoomLevel sẽ được dời vào phiên bản 3.0. Xin sử dụng thiết lập độ phân tích tối thiểu / tối đa thay thế, theo hướng dẫn này: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Giao dịch WFS: THÀNH CÔNG ${response}",'commitFailed':"Giao dịch WFS: THẤT BẠI ${response}",'googleWarning':"Không thể tải lớp Google đúng đắn.\x3cbr\x3e\x3cbr\x3eĐể tránh thông báo này lần sau, hãy chọn BaseLayer mới dùng điều khiển chọn lớp ở góc trên phải.\x3cbr\x3e\x3cbr\x3eChắc script thư viện Google Maps hoặc không được bao gồm hoặc không chứa khóa API hợp với website của bạn.\x3cbr\x3e\x3cbr\x3e\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eTrợ giúp về tính năng này\x3c/a\x3e cho người phát triển.",'getLayerWarning':"Không thể tải lớp ${layerType} đúng đắn.\x3cbr\x3e\x3cbr\x3eĐể tránh thông báo này lần sau, hãy chọn BaseLayer mới dùng điều khiển chọn lớp ở góc trên phải.\x3cbr\x3e\x3cbr\x3eChắc script thư viện ${layerLib} không được bao gồm đúng kiểu.\x3cbr\x3e\x3cbr\x3e\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eTrợ giúp về tính năng này\x3c/a\x3e cho người phát triển.",'scale':"Tỷ lệ = 1 : ${scaleDenom}",'W':"T",'E':"Đ",'N':"B",'S':"N",'layerAlreadyAdded':"Bạn muốn thêm lớp ${layerName} vào bản đồ, nhưng lớp này đã được thêm",'reprojectDeprecated':"Bạn đang áp dụng chế độ “reproject” vào lớp ${layerName}. Chế độ này đã bị phản đối: nó có mục đích hỗ trợ lấp dữ liệu trên các nền bản đồ thương mại; nên thực hiện hiệu ứng đó dùng tính năng Mercator Hình cầu. Có sẵn thêm chi tiết tại http://trac.openlayers.org/wiki/SphericalMercator .",'methodDeprecated':"Phương thức này đã bị phản đối và sẽ bị dời vào phiên bản 3.0. Xin hãy sử dụng ${newMethod} thay thế.",'boundsAddError':"Cần phải cho cả giá trị x và y vào hàm add.",'lonlatAddError':"Cần phải cho cả giá trị lon và lat vào hàm add.",'pixelAddError':"Cần phải cho cả giá trị x và y vào hàm add.",'unsupportedGeometryType':"Không hỗ trợ kiểu địa lý: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition bị thất bại: nguyên tố với ID ${elemId} có thể ở chỗ sai.",'filterEvaluateNotImplemented':"chưa hỗ trợ evaluate cho loại bộ lọc này."});OpenLayers.Popup.AnchoredBubble=OpenLayers.Class(OpenLayers.Popup.Anchored,{rounded:false,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){this.padding=new OpenLayers.Bounds(0,OpenLayers.Popup.AnchoredBubble.CORNER_SIZE,0,OpenLayers.Popup.AnchoredBubble.CORNER_SIZE);OpenLayers.Popup.Anchored.prototype.initialize.apply(this,arguments);},draw:function(px){OpenLayers.Popup.Anchored.prototype.draw.apply(this,arguments);this.setContentHTML();this.setBackgroundColor();this.setOpacity();return this.div;},updateRelativePosition:function(){this.setRicoCorners();},setSize:function(contentSize){OpenLayers.Popup.Anchored.prototype.setSize.apply(this,arguments);this.setRicoCorners();},setBackgroundColor:function(color){if(color!=undefined){this.backgroundColor=color;}
+if(this.div!=null){if(this.contentDiv!=null){this.div.style.background="transparent";OpenLayers.Rico.Corner.changeColor(this.groupDiv,this.backgroundColor);}}},setOpacity:function(opacity){OpenLayers.Popup.Anchored.prototype.setOpacity.call(this,opacity);if(this.div!=null){if(this.groupDiv!=null){OpenLayers.Rico.Corner.changeOpacity(this.groupDiv,this.opacity);}}},setBorder:function(border){this.border=0;},setRicoCorners:function(){var corners=this.getCornersToRound(this.relativePosition);var options={corners:corners,color:this.backgroundColor,bgColor:"transparent",blend:false};if(!this.rounded){OpenLayers.Rico.Corner.round(this.div,options);this.rounded=true;}else{OpenLayers.Rico.Corner.reRound(this.groupDiv,options);this.setBackgroundColor();this.setOpacity();}},getCornersToRound:function(){var corners=['tl','tr','bl','br'];var corner=OpenLayers.Bounds.oppositeQuadrant(this.relativePosition);OpenLayers.Util.removeItem(corners,corner);return corners.join(" ");},CLASS_NAME:"OpenLayers.Popup.AnchoredBubble"});OpenLayers.Popup.AnchoredBubble.CORNER_SIZE=5;OpenLayers.Popup.Framed=OpenLayers.Class(OpenLayers.Popup.Anchored,{imageSrc:null,imageSize:null,isAlphaImage:false,positionBlocks:null,blocks:null,fixedRelativePosition:false,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){OpenLayers.Popup.Anchored.prototype.initialize.apply(this,arguments);if(this.fixedRelativePosition){this.updateRelativePosition();this.calculateRelativePosition=function(px){return this.relativePosition;};}
+this.contentDiv.style.position="absolute";this.contentDiv.style.zIndex=1;if(closeBox){this.closeDiv.style.zIndex=1;}
+this.groupDiv.style.position="absolute";this.groupDiv.style.top="0px";this.groupDiv.style.left="0px";this.groupDiv.style.height="100%";this.groupDiv.style.width="100%";},destroy:function(){this.imageSrc=null;this.imageSize=null;this.isAlphaImage=null;this.fixedRelativePosition=false;this.positionBlocks=null;for(var i=0;i<this.blocks.length;i++){var block=this.blocks[i];if(block.image){block.div.removeChild(block.image);}
+block.image=null;if(block.div){this.groupDiv.removeChild(block.div);}
+block.div=null;}
+this.blocks=null;OpenLayers.Popup.Anchored.prototype.destroy.apply(this,arguments);},setBackgroundColor:function(color){},setBorder:function(){},setOpacity:function(opacity){},setSize:function(contentSize){OpenLayers.Popup.Anchored.prototype.setSize.apply(this,arguments);this.updateBlocks();},updateRelativePosition:function(){this.padding=this.positionBlocks[this.relativePosition].padding;if(this.closeDiv){var contentDivPadding=this.getContentDivPadding();this.closeDiv.style.right=contentDivPadding.right+
+this.padding.right+"px";this.closeDiv.style.top=contentDivPadding.top+
+this.padding.top+"px";}
+this.updateBlocks();},calculateNewPx:function(px){var newPx=OpenLayers.Popup.Anchored.prototype.calculateNewPx.apply(this,arguments);newPx=newPx.offset(this.positionBlocks[this.relativePosition].offset);return newPx;},createBlocks:function(){this.blocks=[];var firstPosition=null;for(var key in this.positionBlocks){firstPosition=key;break;}
+var position=this.positionBlocks[firstPosition];for(var i=0;i<position.blocks.length;i++){var block={};this.blocks.push(block);var divId=this.id+'_FrameDecorationDiv_'+i;block.div=OpenLayers.Util.createDiv(divId,null,null,null,"absolute",null,"hidden",null);var imgId=this.id+'_FrameDecorationImg_'+i;var imageCreator=(this.isAlphaImage)?OpenLayers.Util.createAlphaImageDiv:OpenLayers.Util.createImage;block.image=imageCreator(imgId,null,this.imageSize,this.imageSrc,"absolute",null,null,null);block.div.appendChild(block.image);this.groupDiv.appendChild(block.div);}},updateBlocks:function(){if(!this.blocks){this.createBlocks();}
+if(this.size&&this.relativePosition){var position=this.positionBlocks[this.relativePosition];for(var i=0;i<position.blocks.length;i++){var positionBlock=position.blocks[i];var block=this.blocks[i];var l=positionBlock.anchor.left;var b=positionBlock.anchor.bottom;var r=positionBlock.anchor.right;var t=positionBlock.anchor.top;var w=(isNaN(positionBlock.size.w))?this.size.w-(r+l):positionBlock.size.w;var h=(isNaN(positionBlock.size.h))?this.size.h-(b+t):positionBlock.size.h;block.div.style.width=(w<0?0:w)+'px';block.div.style.height=(h<0?0:h)+'px';block.div.style.left=(l!=null)?l+'px':'';block.div.style.bottom=(b!=null)?b+'px':'';block.div.style.right=(r!=null)?r+'px':'';block.div.style.top=(t!=null)?t+'px':'';block.image.style.left=positionBlock.position.x+'px';block.image.style.top=positionBlock.position.y+'px';}
+this.contentDiv.style.left=this.padding.left+"px";this.contentDiv.style.top=this.padding.top+"px";}},CLASS_NAME:"OpenLayers.Popup.Framed"});OpenLayers.Projection=OpenLayers.Class({proj:null,projCode:null,initialize:function(projCode,options){OpenLayers.Util.extend(this,options);this.projCode=projCode;if(window.Proj4js){this.proj=new Proj4js.Proj(projCode);}},getCode:function(){return this.proj?this.proj.srsCode:this.projCode;},getUnits:function(){return this.proj?this.proj.units:null;},toString:function(){return this.getCode();},equals:function(projection){if(projection&&projection.getCode){return this.getCode()==projection.getCode();}else{return false;}},destroy:function(){delete this.proj;delete this.projCode;},CLASS_NAME:"OpenLayers.Projection"});OpenLayers.Projection.transforms={};OpenLayers.Projection.addTransform=function(from,to,method){if(!OpenLayers.Projection.transforms[from]){OpenLayers.Projection.transforms[from]={};}
+OpenLayers.Projection.transforms[from][to]=method;};OpenLayers.Projection.transform=function(point,source,dest){if(source.proj&&dest.proj){point=Proj4js.transform(source.proj,dest.proj,point);}else if(source&&dest&&OpenLayers.Projection.transforms[source.getCode()]&&OpenLayers.Projection.transforms[source.getCode()][dest.getCode()]){OpenLayers.Projection.transforms[source.getCode()][dest.getCode()](point);}
+return point;};OpenLayers.Protocol.WFS.v1=OpenLayers.Class(OpenLayers.Protocol,{version:null,srsName:"EPSG:4326",featureType:null,featureNS:null,geometryName:"the_geom",schema:null,featurePrefix:"feature",formatOptions:null,readFormat:null,initialize:function(options){OpenLayers.Protocol.prototype.initialize.apply(this,[options]);if(!options.format){this.format=OpenLayers.Format.WFST(OpenLayers.Util.extend({version:this.version,featureType:this.featureType,featureNS:this.featureNS,featurePrefix:this.featurePrefix,geometryName:this.geometryName,srsName:this.srsName,schema:this.schema},this.formatOptions));}
+if(!this.featureNS&&this.featurePrefix){var readNode=this.format.readNode;this.format.readNode=function(node,obj){if(!this.featureNS&&node.prefix==this.featurePrefix){this.featureNS=node.namespaceURI;this.setNamespace("feature",this.featureNS);}
+return readNode.apply(this,arguments);};}},destroy:function(){if(this.options&&!this.options.format){this.format.destroy();}
+this.format=null;OpenLayers.Protocol.prototype.destroy.apply(this);},read:function(options){OpenLayers.Protocol.prototype.read.apply(this,arguments);options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options||{});var response=new OpenLayers.Protocol.Response({requestType:"read"});var data=OpenLayers.Format.XML.prototype.write.apply(this.format,[this.format.writeNode("wfs:GetFeature",options)]);response.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleRead,response,options),params:options.params,headers:options.headers,data:data});return response;},handleRead:function(response,options){if(options.callback){var request=response.priv;if(request.status>=200&&request.status<300){response.features=this.parseFeatures(request);response.code=OpenLayers.Protocol.Response.SUCCESS;}else{response.code=OpenLayers.Protocol.Response.FAILURE;}
+options.callback.call(options.scope,response);}},parseFeatures:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
+if(!doc||doc.length<=0){return null;}
+return(this.readFormat!==null)?this.readFormat.read(doc):this.format.read(doc);},commit:function(features,options){options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options);var response=new OpenLayers.Protocol.Response({requestType:"commit",reqFeatures:features});response.priv=OpenLayers.Request.POST({url:options.url,data:this.format.write(features,options),callback:this.createCallback(this.handleCommit,response,options)});return response;},handleCommit:function(response,options){if(options.callback){var request=response.priv;var data=request.responseXML;if(!data||!data.documentElement){data=request.responseText;}
+var obj=this.format.read(data)||{};response.insertIds=obj.insertIds||[];response.code=(obj.success)?OpenLayers.Protocol.Response.SUCCESS:OpenLayers.Protocol.Response.FAILURE;options.callback.call(options.scope,response);}},filterDelete:function(filter,options){options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options);var response=new OpenLayers.Protocol.Response({requestType:"commit"});var root=this.format.createElementNSPlus("wfs:Transaction",{attributes:{service:"WFS",version:this.version}});var deleteNode=this.format.createElementNSPlus("wfs:Delete",{attributes:{typeName:(options.featureNS?this.featurePrefix+":":"")+
+options.featureType}});if(options.featureNS){deleteNode.setAttribute("xmlns:"+this.featurePrefix,options.featureNS);}
+var filterNode=this.format.writeNode("ogc:Filter",filter);deleteNode.appendChild(filterNode);root.appendChild(deleteNode);var data=OpenLayers.Format.XML.prototype.write.apply(this.format,[root]);return OpenLayers.Request.POST({url:this.url,callback:options.callback||function(){},data:data});},abort:function(response){if(response){response.priv.abort();}},CLASS_NAME:"OpenLayers.Protocol.WFS.v1"});OpenLayers.Renderer.SVG=OpenLayers.Class(OpenLayers.Renderer.Elements,{xmlns:"http://www.w3.org/2000/svg",xlinkns:"http://www.w3.org/1999/xlink",MAX_PIXEL:15000,translationParameters:null,symbolMetrics:null,isGecko:null,supportUse:null,initialize:function(containerID){if(!this.supported()){return;}
+OpenLayers.Renderer.Elements.prototype.initialize.apply(this,arguments);this.translationParameters={x:0,y:0};this.supportUse=(navigator.userAgent.toLowerCase().indexOf("applewebkit/5")==-1);this.isGecko=(navigator.userAgent.toLowerCase().indexOf("gecko/")!=-1);this.symbolMetrics={};},destroy:function(){OpenLayers.Renderer.Elements.prototype.destroy.apply(this,arguments);},supported:function(){var svgFeature="http://www.w3.org/TR/SVG11/feature#";return(document.implementation&&(document.implementation.hasFeature("org.w3c.svg","1.0")||document.implementation.hasFeature(svgFeature+"SVG","1.1")||document.implementation.hasFeature(svgFeature+"BasicStructure","1.1")));},inValidRange:function(x,y,xyOnly){var left=x+(xyOnly?0:this.translationParameters.x);var top=y+(xyOnly?0:this.translationParameters.y);return(left>=-this.MAX_PIXEL&&left<=this.MAX_PIXEL&&top>=-this.MAX_PIXEL&&top<=this.MAX_PIXEL);},setExtent:function(extent,resolutionChanged){OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,arguments);var resolution=this.getResolution();var left=-extent.left/resolution;var top=extent.top/resolution;if(resolutionChanged){this.left=left;this.top=top;var extentString="0 0 "+this.size.w+" "+this.size.h;this.rendererRoot.setAttributeNS(null,"viewBox",extentString);this.translate(0,0);return true;}else{var inRange=this.translate(left-this.left,top-this.top);if(!inRange){this.setExtent(extent,true);}
+return inRange;}},translate:function(x,y){if(!this.inValidRange(x,y,true)){return false;}else{var transformString="";if(x||y){transformString="translate("+x+","+y+")";}
+this.root.setAttributeNS(null,"transform",transformString);this.translationParameters={x:x,y:y};return true;}},setSize:function(size){OpenLayers.Renderer.prototype.setSize.apply(this,arguments);this.rendererRoot.setAttributeNS(null,"width",this.size.w);this.rendererRoot.setAttributeNS(null,"height",this.size.h);},getNodeType:function(geometry,style){var nodeType=null;switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":if(style.externalGraphic){nodeType="image";}else if(this.isComplexSymbol(style.graphicName)){nodeType=this.supportUse===false?"svg":"use";}else{nodeType="circle";}
+break;case"OpenLayers.Geometry.Rectangle":nodeType="rect";break;case"OpenLayers.Geometry.LineString":nodeType="polyline";break;case"OpenLayers.Geometry.LinearRing":nodeType="polygon";break;case"OpenLayers.Geometry.Polygon":case"OpenLayers.Geometry.Curve":case"OpenLayers.Geometry.Surface":nodeType="path";break;default:break;}
+return nodeType;},setStyle:function(node,style,options){style=style||node._style;options=options||node._options;var r=parseFloat(node.getAttributeNS(null,"r"));var widthFactor=1;var pos;if(node._geometryClass=="OpenLayers.Geometry.Point"&&r){node.style.visibility="";if(style.graphic===false){node.style.visibility="hidden";}else if(style.externalGraphic){pos=this.getPosition(node);if(style.graphicTitle){node.setAttributeNS(null,"title",style.graphicTitle);}
+if(style.graphicWidth&&style.graphicHeight){node.setAttributeNS(null,"preserveAspectRatio","none");}
+var width=style.graphicWidth||style.graphicHeight;var height=style.graphicHeight||style.graphicWidth;width=width?width:style.pointRadius*2;height=height?height:style.pointRadius*2;var xOffset=(style.graphicXOffset!=undefined)?style.graphicXOffset:-(0.5*width);var yOffset=(style.graphicYOffset!=undefined)?style.graphicYOffset:-(0.5*height);var opacity=style.graphicOpacity||style.fillOpacity;node.setAttributeNS(null,"x",(pos.x+xOffset).toFixed());node.setAttributeNS(null,"y",(pos.y+yOffset).toFixed());node.setAttributeNS(null,"width",width);node.setAttributeNS(null,"height",height);node.setAttributeNS(this.xlinkns,"href",style.externalGraphic);node.setAttributeNS(null,"style","opacity: "+opacity);}else if(this.isComplexSymbol(style.graphicName)){var offset=style.pointRadius*3;var size=offset*2;var id=this.importSymbol(style.graphicName);pos=this.getPosition(node);widthFactor=this.symbolMetrics[id][0]*3/size;var parent=node.parentNode;var nextSibling=node.nextSibling;if(parent){parent.removeChild(node);}
+if(this.supportUse===false){var src=document.getElementById(id);node.firstChild&&node.removeChild(node.firstChild);node.appendChild(src.firstChild.cloneNode(true));node.setAttributeNS(null,"viewBox",src.getAttributeNS(null,"viewBox"));}else{node.setAttributeNS(this.xlinkns,"href","#"+id);}
+node.setAttributeNS(null,"width",size);node.setAttributeNS(null,"height",size);node.setAttributeNS(null,"x",pos.x-offset);node.setAttributeNS(null,"y",pos.y-offset);if(nextSibling){parent.insertBefore(node,nextSibling);}else if(parent){parent.appendChild(node);}}else{node.setAttributeNS(null,"r",style.pointRadius);}
+var rotation=style.rotation;if((rotation!==undefined||node._rotation!==undefined)&&pos){node._rotation=rotation;rotation|=0;if(node.nodeName!=="svg"){node.setAttributeNS(null,"transform","rotate("+rotation+" "+pos.x+" "+
+pos.y+")");}else{var metrics=this.symbolMetrics[id];node.firstChild.setAttributeNS(null,"transform","rotate("+style.rotation+" "+metrics[1]+" "+metrics[2]+")");}}}
+if(options.isFilled){node.setAttributeNS(null,"fill",style.fillColor);node.setAttributeNS(null,"fill-opacity",style.fillOpacity);}else{node.setAttributeNS(null,"fill","none");}
+if(options.isStroked){node.setAttributeNS(null,"stroke",style.strokeColor);node.setAttributeNS(null,"stroke-opacity",style.strokeOpacity);node.setAttributeNS(null,"stroke-width",style.strokeWidth*widthFactor);node.setAttributeNS(null,"stroke-linecap",style.strokeLinecap||"round");node.setAttributeNS(null,"stroke-linejoin","round");style.strokeDashstyle&&node.setAttributeNS(null,"stroke-dasharray",this.dashStyle(style,widthFactor));}else{node.setAttributeNS(null,"stroke","none");}
+if(style.pointerEvents){node.setAttributeNS(null,"pointer-events",style.pointerEvents);}
+if(style.cursor!=null){node.setAttributeNS(null,"cursor",style.cursor);}
+return node;},dashStyle:function(style,widthFactor){var w=style.strokeWidth*widthFactor;var str=style.strokeDashstyle;switch(str){case'solid':return'none';case'dot':return[1,4*w].join();case'dash':return[4*w,4*w].join();case'dashdot':return[4*w,4*w,1,4*w].join();case'longdash':return[8*w,4*w].join();case'longdashdot':return[8*w,4*w,1,4*w].join();default:return OpenLayers.String.trim(str).replace(/\s+/g,",");}},createNode:function(type,id){var node=document.createElementNS(this.xmlns,type);if(id){node.setAttributeNS(null,"id",id);}
+return node;},nodeTypeCompare:function(node,type){return(type==node.nodeName);},createRenderRoot:function(){return this.nodeFactory(this.container.id+"_svgRoot","svg");},createRoot:function(suffix){return this.nodeFactory(this.container.id+suffix,"g");},createDefs:function(){var defs=this.nodeFactory(this.container.id+"_defs","defs");this.rendererRoot.appendChild(defs);return defs;},drawPoint:function(node,geometry){return this.drawCircle(node,geometry,1);},drawCircle:function(node,geometry,radius){var resolution=this.getResolution();var x=(geometry.x/resolution+this.left);var y=(this.top-geometry.y/resolution);if(this.inValidRange(x,y)){node.setAttributeNS(null,"cx",x);node.setAttributeNS(null,"cy",y);node.setAttributeNS(null,"r",radius);return node;}else{return false;}},drawLineString:function(node,geometry){var componentsResult=this.getComponentsString(geometry.components);if(componentsResult.path){node.setAttributeNS(null,"points",componentsResult.path);return(componentsResult.complete?node:null);}else{return false;}},drawLinearRing:function(node,geometry){var componentsResult=this.getComponentsString(geometry.components);if(componentsResult.path){node.setAttributeNS(null,"points",componentsResult.path);return(componentsResult.complete?node:null);}else{return false;}},drawPolygon:function(node,geometry){var d="";var draw=true;var complete=true;var linearRingResult,path;for(var j=0,len=geometry.components.length;j<len;j++){d+=" M";linearRingResult=this.getComponentsString(geometry.components[j].components," ");path=linearRingResult.path;if(path){d+=" "+path;complete=linearRingResult.complete&&complete;}else{draw=false;}}
+d+=" z";if(draw){node.setAttributeNS(null,"d",d);node.setAttributeNS(null,"fill-rule","evenodd");return complete?node:null;}else{return false;}},drawRectangle:function(node,geometry){var resolution=this.getResolution();var x=(geometry.x/resolution+this.left);var y=(this.top-geometry.y/resolution);if(this.inValidRange(x,y)){node.setAttributeNS(null,"x",x);node.setAttributeNS(null,"y",y);node.setAttributeNS(null,"width",geometry.width/resolution);node.setAttributeNS(null,"height",geometry.height/resolution);return node;}else{return false;}},drawSurface:function(node,geometry){var d=null;var draw=true;for(var i=0,len=geometry.components.length;i<len;i++){if((i%3)==0&&(i/3)==0){var component=this.getShortString(geometry.components[i]);if(!component){draw=false;}
+d="M "+component;}else if((i%3)==1){var component=this.getShortString(geometry.components[i]);if(!component){draw=false;}
+d+=" C "+component;}else{var component=this.getShortString(geometry.components[i]);if(!component){draw=false;}
+d+=" "+component;}}
+d+=" Z";if(draw){node.setAttributeNS(null,"d",d);return node;}else{return false;}},drawText:function(featureId,style,location){var resolution=this.getResolution();var x=(location.x/resolution+this.left);var y=(location.y/resolution-this.top);var label=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX,"text");var tspan=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX+"_tspan","tspan");label.setAttributeNS(null,"x",x);label.setAttributeNS(null,"y",-y);if(style.fontColor){label.setAttributeNS(null,"fill",style.fontColor);}
+if(style.fontOpacity){label.setAttributeNS(null,"opacity",style.fontOpacity);}
+if(style.fontFamily){label.setAttributeNS(null,"font-family",style.fontFamily);}
+if(style.fontSize){label.setAttributeNS(null,"font-size",style.fontSize);}
+if(style.fontWeight){label.setAttributeNS(null,"font-weight",style.fontWeight);}
+if(style.labelSelect===true){label.setAttributeNS(null,"pointer-events","visible");label._featureId=featureId;tspan._featureId=featureId;tspan._geometry=location;tspan._geometryClass=location.CLASS_NAME;}else{label.setAttributeNS(null,"pointer-events","none");}
+var align=style.labelAlign||"cm";label.setAttributeNS(null,"text-anchor",OpenLayers.Renderer.SVG.LABEL_ALIGN[align[0]]||"middle");if(this.isGecko){label.setAttributeNS(null,"dominant-baseline",OpenLayers.Renderer.SVG.LABEL_ALIGN[align[1]]||"central");}else{tspan.setAttributeNS(null,"baseline-shift",OpenLayers.Renderer.SVG.LABEL_VSHIFT[align[1]]||"-35%");}
+tspan.textContent=style.label;if(!label.parentNode){label.appendChild(tspan);this.textRoot.appendChild(label);}},getComponentsString:function(components,separator){var renderCmp=[];var complete=true;var len=components.length;var strings=[];var str,component;for(var i=0;i<len;i++){component=components[i];renderCmp.push(component);str=this.getShortString(component);if(str){strings.push(str);}else{if(i>0){if(this.getShortString(components[i-1])){strings.push(this.clipLine(components[i],components[i-1]));}}
+if(i<len-1){if(this.getShortString(components[i+1])){strings.push(this.clipLine(components[i],components[i+1]));}}
+complete=false;}}
+return{path:strings.join(separator||","),complete:complete};},clipLine:function(badComponent,goodComponent){if(goodComponent.equals(badComponent)){return"";}
+var resolution=this.getResolution();var maxX=this.MAX_PIXEL-this.translationParameters.x;var maxY=this.MAX_PIXEL-this.translationParameters.y;var x1=goodComponent.x/resolution+this.left;var y1=this.top-goodComponent.y/resolution;var x2=badComponent.x/resolution+this.left;var y2=this.top-badComponent.y/resolution;var k;if(x2<-maxX||x2>maxX){k=(y2-y1)/(x2-x1);x2=x2<0?-maxX:maxX;y2=y1+(x2-x1)*k;}
+if(y2<-maxY||y2>maxY){k=(x2-x1)/(y2-y1);y2=y2<0?-maxY:maxY;x2=x1+(y2-y1)*k;}
+return x2+","+y2;},getShortString:function(point){var resolution=this.getResolution();var x=(point.x/resolution+this.left);var y=(this.top-point.y/resolution);if(this.inValidRange(x,y)){return x+","+y;}else{return false;}},getPosition:function(node){return({x:parseFloat(node.getAttributeNS(null,"cx")),y:parseFloat(node.getAttributeNS(null,"cy"))});},importSymbol:function(graphicName){if(!this.defs){this.defs=this.createDefs();}
+var id=this.container.id+"-"+graphicName;if(document.getElementById(id)!=null){return id;}
+var symbol=OpenLayers.Renderer.symbol[graphicName];if(!symbol){throw new Error(graphicName+' is not a valid symbol name');}
+var symbolNode=this.nodeFactory(id,"symbol");var node=this.nodeFactory(null,"polygon");symbolNode.appendChild(node);var symbolExtent=new OpenLayers.Bounds(Number.MAX_VALUE,Number.MAX_VALUE,0,0);var points=[];var x,y;for(var i=0;i<symbol.length;i=i+2){x=symbol[i];y=symbol[i+1];symbolExtent.left=Math.min(symbolExtent.left,x);symbolExtent.bottom=Math.min(symbolExtent.bottom,y);symbolExtent.right=Math.max(symbolExtent.right,x);symbolExtent.top=Math.max(symbolExtent.top,y);points.push(x,",",y);}
+node.setAttributeNS(null,"points",points.join(" "));var width=symbolExtent.getWidth();var height=symbolExtent.getHeight();var viewBox=[symbolExtent.left-width,symbolExtent.bottom-height,width*3,height*3];symbolNode.setAttributeNS(null,"viewBox",viewBox.join(" "));this.symbolMetrics[id]=[Math.max(width,height),symbolExtent.getCenterLonLat().lon,symbolExtent.getCenterLonLat().lat];this.defs.appendChild(symbolNode);return symbolNode.id;},getFeatureIdFromEvent:function(evt){var featureId=OpenLayers.Renderer.Elements.prototype.getFeatureIdFromEvent.apply(this,arguments);if(this.supportUse===false&&!featureId){var target=evt.target;featureId=target.parentNode&&target!=this.rendererRoot&&target.parentNode._featureId;}
+return featureId;},CLASS_NAME:"OpenLayers.Renderer.SVG"});OpenLayers.Renderer.SVG.LABEL_ALIGN={"l":"start","r":"end","b":"bottom","t":"hanging"};OpenLayers.Renderer.SVG.LABEL_VSHIFT={"t":"-70%","b":"0"};OpenLayers.Renderer.VML=OpenLayers.Class(OpenLayers.Renderer.Elements,{xmlns:"urn:schemas-microsoft-com:vml",symbolCache:{},offset:null,initialize:function(containerID){if(!this.supported()){return;}
+if(!document.namespaces.olv){document.namespaces.add("olv",this.xmlns);var style=document.createStyleSheet();var shapes=['shape','rect','oval','fill','stroke','imagedata','group','textbox'];for(var i=0,len=shapes.length;i<len;i++){style.addRule('olv\\:'+shapes[i],"behavior: url(#default#VML); "+"position: absolute; display: inline-block;");}}
+OpenLayers.Renderer.Elements.prototype.initialize.apply(this,arguments);},destroy:function(){OpenLayers.Renderer.Elements.prototype.destroy.apply(this,arguments);},supported:function(){return!!(document.namespaces);},setExtent:function(extent,resolutionChanged){OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,arguments);var resolution=this.getResolution();var left=(extent.left/resolution)|0;var top=(extent.top/resolution-this.size.h)|0;if(resolutionChanged||!this.offset){this.offset={x:left,y:top};left=0;top=0;}else{left=left-this.offset.x;top=top-this.offset.y;}
+var org=left+" "+top;this.root.coordorigin=org;var roots=[this.root,this.vectorRoot,this.textRoot];var root;for(var i=0,len=roots.length;i<len;++i){root=roots[i];var size=this.size.w+" "+this.size.h;root.coordsize=size;}
+this.root.style.flip="y";return true;},setSize:function(size){OpenLayers.Renderer.prototype.setSize.apply(this,arguments);var roots=[this.rendererRoot,this.root,this.vectorRoot,this.textRoot];var w=this.size.w+"px";var h=this.size.h+"px";var root;for(var i=0,len=roots.length;i<len;++i){root=roots[i];root.style.width=w;root.style.height=h;}},getNodeType:function(geometry,style){var nodeType=null;switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":if(style.externalGraphic){nodeType="olv:rect";}else if(this.isComplexSymbol(style.graphicName)){nodeType="olv:shape";}else{nodeType="olv:oval";}
+break;case"OpenLayers.Geometry.Rectangle":nodeType="olv:rect";break;case"OpenLayers.Geometry.LineString":case"OpenLayers.Geometry.LinearRing":case"OpenLayers.Geometry.Polygon":case"OpenLayers.Geometry.Curve":case"OpenLayers.Geometry.Surface":nodeType="olv:shape";break;default:break;}
+return nodeType;},setStyle:function(node,style,options,geometry){style=style||node._style;options=options||node._options;var fillColor=style.fillColor;if(node._geometryClass==="OpenLayers.Geometry.Point"){if(style.externalGraphic){if(style.graphicTitle){node.title=style.graphicTitle;}
+var width=style.graphicWidth||style.graphicHeight;var height=style.graphicHeight||style.graphicWidth;width=width?width:style.pointRadius*2;height=height?height:style.pointRadius*2;var resolution=this.getResolution();var xOffset=(style.graphicXOffset!=undefined)?style.graphicXOffset:-(0.5*width);var yOffset=(style.graphicYOffset!=undefined)?style.graphicYOffset:-(0.5*height);node.style.left=(((geometry.x/resolution-this.offset.x)+xOffset)|0)+"px";node.style.top=(((geometry.y/resolution-this.offset.y)-(yOffset+height))|0)+"px";node.style.width=width+"px";node.style.height=height+"px";node.style.flip="y";fillColor="none";options.isStroked=false;}else if(this.isComplexSymbol(style.graphicName)){var cache=this.importSymbol(style.graphicName);node.path=cache.path;node.coordorigin=cache.left+","+cache.bottom;var size=cache.size;node.coordsize=size+","+size;this.drawCircle(node,geometry,style.pointRadius);node.style.flip="y";}else{this.drawCircle(node,geometry,style.pointRadius);}}
+if(options.isFilled){node.fillcolor=fillColor;}else{node.filled="false";}
+var fills=node.getElementsByTagName("fill");var fill=(fills.length==0)?null:fills[0];if(!options.isFilled){if(fill){node.removeChild(fill);}}else{if(!fill){fill=this.createNode('olv:fill',node.id+"_fill");}
+fill.opacity=style.fillOpacity;if(node._geometryClass==="OpenLayers.Geometry.Point"&&style.externalGraphic){if(style.graphicOpacity){fill.opacity=style.graphicOpacity;}
+fill.src=style.externalGraphic;fill.type="frame";if(!(style.graphicWidth&&style.graphicHeight)){fill.aspect="atmost";}}
+if(fill.parentNode!=node){node.appendChild(fill);}}
+var rotation=style.rotation;if((rotation!==undefined||node._rotation!==undefined)){node._rotation=rotation;if(style.externalGraphic){this.graphicRotate(node,xOffset,yOffset,style);fill.opacity=0;}else if(node._geometryClass==="OpenLayers.Geometry.Point"){node.style.rotation=rotation||0;}}
+var strokes=node.getElementsByTagName("stroke");var stroke=(strokes.length==0)?null:strokes[0];if(!options.isStroked){node.stroked=false;if(stroke){stroke.on=false;}}else{if(!stroke){stroke=this.createNode('olv:stroke',node.id+"_stroke");node.appendChild(stroke);}
+stroke.on=true;stroke.color=style.strokeColor;stroke.weight=style.strokeWidth+"px";stroke.opacity=style.strokeOpacity;stroke.endcap=style.strokeLinecap=='butt'?'flat':(style.strokeLinecap||'round');if(style.strokeDashstyle){stroke.dashstyle=this.dashStyle(style);}}
+if(style.cursor!="inherit"&&style.cursor!=null){node.style.cursor=style.cursor;}
+return node;},graphicRotate:function(node,xOffset,yOffset,style){var style=style||node._style;var rotation=style.rotation||0;var aspectRatio,size;if(!(style.graphicWidth&&style.graphicHeight)){var img=new Image();img.onreadystatechange=OpenLayers.Function.bind(function(){if(img.readyState=="complete"||img.readyState=="interactive"){aspectRatio=img.width/img.height;size=Math.max(style.pointRadius*2,style.graphicWidth||0,style.graphicHeight||0);xOffset=xOffset*aspectRatio;style.graphicWidth=size*aspectRatio;style.graphicHeight=size;this.graphicRotate(node,xOffset,yOffset,style);}},this);img.src=style.externalGraphic;return;}else{size=Math.max(style.graphicWidth,style.graphicHeight);aspectRatio=style.graphicWidth/style.graphicHeight;}
+var width=Math.round(style.graphicWidth||size*aspectRatio);var height=Math.round(style.graphicHeight||size);node.style.width=width+"px";node.style.height=height+"px";var image=document.getElementById(node.id+"_image");if(!image){image=this.createNode("olv:imagedata",node.id+"_image");node.appendChild(image);}
+image.style.width=width+"px";image.style.height=height+"px";image.src=style.externalGraphic;image.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader("+"src='', sizingMethod='scale')";var rot=rotation*Math.PI/180;var sintheta=Math.sin(rot);var costheta=Math.cos(rot);var filter="progid:DXImageTransform.Microsoft.Matrix(M11="+costheta+",M12="+(-sintheta)+",M21="+sintheta+",M22="+costheta+",SizingMethod='auto expand')\n";var opacity=style.graphicOpacity||style.fillOpacity;if(opacity&&opacity!=1){filter+="progid:DXImageTransform.Microsoft.BasicImage(opacity="+
+opacity+")\n";}
+node.style.filter=filter;var centerPoint=new OpenLayers.Geometry.Point(-xOffset,-yOffset);var imgBox=new OpenLayers.Bounds(0,0,width,height).toGeometry();imgBox.rotate(style.rotation,centerPoint);var imgBounds=imgBox.getBounds();node.style.left=Math.round(parseInt(node.style.left)+imgBounds.left)+"px";node.style.top=Math.round(parseInt(node.style.top)-imgBounds.bottom)+"px";},postDraw:function(node){node.style.visibility="visible";var fillColor=node._style.fillColor;var strokeColor=node._style.strokeColor;if(fillColor=="none"&&node.fillcolor!=fillColor){node.fillcolor=fillColor;}
+if(strokeColor=="none"&&node.strokecolor!=strokeColor){node.strokecolor=strokeColor;}},setNodeDimension:function(node,geometry){var bbox=geometry.getBounds();if(bbox){var resolution=this.getResolution();var scaledBox=new OpenLayers.Bounds((bbox.left/resolution-this.offset.x)|0,(bbox.bottom/resolution-this.offset.y)|0,(bbox.right/resolution-this.offset.x)|0,(bbox.top/resolution-this.offset.y)|0);node.style.left=scaledBox.left+"px";node.style.top=scaledBox.top+"px";node.style.width=scaledBox.getWidth()+"px";node.style.height=scaledBox.getHeight()+"px";node.coordorigin=scaledBox.left+" "+scaledBox.top;node.coordsize=scaledBox.getWidth()+" "+scaledBox.getHeight();}},dashStyle:function(style){var dash=style.strokeDashstyle;switch(dash){case'solid':case'dot':case'dash':case'dashdot':case'longdash':case'longdashdot':return dash;default:var parts=dash.split(/[ ,]/);if(parts.length==2){if(1*parts[0]>=2*parts[1]){return"longdash";}
+return(parts[0]==1||parts[1]==1)?"dot":"dash";}else if(parts.length==4){return(1*parts[0]>=2*parts[1])?"longdashdot":"dashdot";}
+return"solid";}},createNode:function(type,id){var node=document.createElement(type);if(id){node.id=id;}
+node.unselectable='on';node.onselectstart=OpenLayers.Function.False;return node;},nodeTypeCompare:function(node,type){var subType=type;var splitIndex=subType.indexOf(":");if(splitIndex!=-1){subType=subType.substr(splitIndex+1);}
+var nodeName=node.nodeName;splitIndex=nodeName.indexOf(":");if(splitIndex!=-1){nodeName=nodeName.substr(splitIndex+1);}
+return(subType==nodeName);},createRenderRoot:function(){return this.nodeFactory(this.container.id+"_vmlRoot","div");},createRoot:function(suffix){return this.nodeFactory(this.container.id+suffix,"olv:group");},drawPoint:function(node,geometry){return this.drawCircle(node,geometry,1);},drawCircle:function(node,geometry,radius){if(!isNaN(geometry.x)&&!isNaN(geometry.y)){var resolution=this.getResolution();node.style.left=(((geometry.x/resolution-this.offset.x)|0)-radius)+"px";node.style.top=(((geometry.y/resolution-this.offset.y)|0)-radius)+"px";var diameter=radius*2;node.style.width=diameter+"px";node.style.height=diameter+"px";return node;}
+return false;},drawLineString:function(node,geometry){return this.drawLine(node,geometry,false);},drawLinearRing:function(node,geometry){return this.drawLine(node,geometry,true);},drawLine:function(node,geometry,closeLine){this.setNodeDimension(node,geometry);var resolution=this.getResolution();var numComponents=geometry.components.length;var parts=new Array(numComponents);var comp,x,y;for(var i=0;i<numComponents;i++){comp=geometry.components[i];x=(comp.x/resolution-this.offset.x)|0;y=(comp.y/resolution-this.offset.y)|0;parts[i]=" "+x+","+y+" l ";}
+var end=(closeLine)?" x e":" e";node.path="m"+parts.join("")+end;return node;},drawPolygon:function(node,geometry){this.setNodeDimension(node,geometry);var resolution=this.getResolution();var path=[];var linearRing,i,j,len,ilen,comp,x,y;for(j=0,len=geometry.components.length;j<len;j++){linearRing=geometry.components[j];path.push("m");for(i=0,ilen=linearRing.components.length;i<ilen;i++){comp=linearRing.components[i];x=(comp.x/resolution-this.offset.x)|0;y=(comp.y/resolution-this.offset.y)|0;path.push(" "+x+","+y);if(i==0){path.push(" l");}}
+path.push(" x ");}
+path.push("e");node.path=path.join("");return node;},drawRectangle:function(node,geometry){var resolution=this.getResolution();node.style.left=((geometry.x/resolution-this.offset.x)|0)+"px";node.style.top=((geometry.y/resolution-this.offset.y)|0)+"px";node.style.width=((geometry.width/resolution)|0)+"px";node.style.height=((geometry.height/resolution)|0)+"px";return node;},drawText:function(featureId,style,location){var label=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX,"olv:rect");var textbox=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX+"_textbox","olv:textbox");var resolution=this.getResolution();label.style.left=((location.x/resolution-this.offset.x)|0)+"px";label.style.top=((location.y/resolution-this.offset.y)|0)+"px";label.style.flip="y";textbox.innerText=style.label;if(style.fontColor){textbox.style.color=style.fontColor;}
+if(style.fontOpacity){textbox.style.filter='alpha(opacity='+(style.fontOpacity*100)+')';}
+if(style.fontFamily){textbox.style.fontFamily=style.fontFamily;}
+if(style.fontSize){textbox.style.fontSize=style.fontSize;}
+if(style.fontWeight){textbox.style.fontWeight=style.fontWeight;}
+if(style.labelSelect===true){label._featureId=featureId;textbox._featureId=featureId;textbox._geometry=location;textbox._geometryClass=location.CLASS_NAME;}
+textbox.style.whiteSpace="nowrap";textbox.inset="1px,0px,0px,0px";if(!label.parentNode){label.appendChild(textbox);this.textRoot.appendChild(label);}
+var align=style.labelAlign||"cm";if(align.length==1){align+="m";}
+var xshift=textbox.clientWidth*(OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(0,1)]);var yshift=textbox.clientHeight*(OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(1,1)]);label.style.left=parseInt(label.style.left)-xshift-1+"px";label.style.top=parseInt(label.style.top)+yshift+"px";},drawSurface:function(node,geometry){this.setNodeDimension(node,geometry);var resolution=this.getResolution();var path=[];var comp,x,y;for(var i=0,len=geometry.components.length;i<len;i++){comp=geometry.components[i];x=(comp.x/resolution-this.offset.x)|0;y=(comp.y/resolution-this.offset.y)|0;if((i%3)==0&&(i/3)==0){path.push("m");}else if((i%3)==1){path.push(" c");}
+path.push(" "+x+","+y);}
+path.push(" x e");node.path=path.join("");return node;},moveRoot:function(renderer){var layer=this.map.getLayer(renderer.container.id);if(layer instanceof OpenLayers.Layer.Vector.RootContainer){layer=this.map.getLayer(this.container.id);}
+layer&&layer.renderer.clear();OpenLayers.Renderer.Elements.prototype.moveRoot.apply(this,arguments);layer&&layer.redraw();},importSymbol:function(graphicName){var id=this.container.id+"-"+graphicName;var cache=this.symbolCache[id];if(cache){return cache;}
+var symbol=OpenLayers.Renderer.symbol[graphicName];if(!symbol){throw new Error(graphicName+' is not a valid symbol name');}
+var symbolExtent=new OpenLayers.Bounds(Number.MAX_VALUE,Number.MAX_VALUE,0,0);var pathitems=["m"];for(var i=0;i<symbol.length;i=i+2){var x=symbol[i];var y=symbol[i+1];symbolExtent.left=Math.min(symbolExtent.left,x);symbolExtent.bottom=Math.min(symbolExtent.bottom,y);symbolExtent.right=Math.max(symbolExtent.right,x);symbolExtent.top=Math.max(symbolExtent.top,y);pathitems.push(x);pathitems.push(y);if(i==0){pathitems.push("l");}}
+pathitems.push("x e");var path=pathitems.join(" ");var diff=(symbolExtent.getWidth()-symbolExtent.getHeight())/2;if(diff>0){symbolExtent.bottom=symbolExtent.bottom-diff;symbolExtent.top=symbolExtent.top+diff;}else{symbolExtent.left=symbolExtent.left+diff;symbolExtent.right=symbolExtent.right-diff;}
+cache={path:path,size:symbolExtent.getWidth(),left:symbolExtent.left,bottom:symbolExtent.bottom};this.symbolCache[id]=cache;return cache;},CLASS_NAME:"OpenLayers.Renderer.VML"});OpenLayers.Renderer.VML.LABEL_SHIFT={"l":0,"c":.5,"r":1,"t":0,"m":.5,"b":1};OpenLayers.Tile=OpenLayers.Class({EVENT_TYPES:["loadstart","loadend","reload","unload"],events:null,id:null,layer:null,url:null,bounds:null,size:null,position:null,isLoading:false,initialize:function(layer,position,bounds,url,size){this.layer=layer;this.position=position.clone();this.bounds=bounds.clone();this.url=url;this.size=size.clone();this.id=OpenLayers.Util.createUniqueID("Tile_");this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);},unload:function(){if(this.isLoading){this.isLoading=false;this.events.triggerEvent("unload");}},destroy:function(){this.layer=null;this.bounds=null;this.size=null;this.position=null;this.events.destroy();this.events=null;},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile(this.layer,this.position,this.bounds,this.url,this.size);}
+OpenLayers.Util.applyDefaults(obj,this);return obj;},draw:function(){var maxExtent=this.layer.maxExtent;var withinMaxExtent=(maxExtent&&this.bounds.intersectsBounds(maxExtent,false));this.shouldDraw=(withinMaxExtent||this.layer.displayOutsideMaxExtent);this.clear();return this.shouldDraw;},moveTo:function(bounds,position,redraw){if(redraw==null){redraw=true;}
+this.bounds=bounds.clone();this.position=position.clone();if(redraw){this.draw();}},clear:function(){},getBoundsFromBaseLayer:function(position){var msg=OpenLayers.i18n('reprojectDeprecated',{'layerName':this.layer.name});OpenLayers.Console.warn(msg);var topLeft=this.layer.map.getLonLatFromLayerPx(position);var bottomRightPx=position.clone();bottomRightPx.x+=this.size.w;bottomRightPx.y+=this.size.h;var bottomRight=this.layer.map.getLonLatFromLayerPx(bottomRightPx);if(topLeft.lon>bottomRight.lon){if(topLeft.lon<0){topLeft.lon=-180-(topLeft.lon+180);}else{bottomRight.lon=180+bottomRight.lon+180;}}
+var bounds=new OpenLayers.Bounds(topLeft.lon,bottomRight.lat,bottomRight.lon,topLeft.lat);return bounds;},showTile:function(){if(this.shouldDraw){this.show();}},show:function(){},hide:function(){},CLASS_NAME:"OpenLayers.Tile"});OpenLayers.Control.MouseToolbar=OpenLayers.Class(OpenLayers.Control.MouseDefaults,{mode:null,buttons:null,direction:"vertical",buttonClicked:null,initialize:function(position,direction){OpenLayers.Control.prototype.initialize.apply(this,arguments);this.position=new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,OpenLayers.Control.MouseToolbar.Y);if(position){this.position=position;}
+if(direction){this.direction=direction;}
+this.measureDivs=[];},destroy:function(){for(var btnId in this.buttons){var btn=this.buttons[btnId];btn.map=null;btn.events.destroy();}
+OpenLayers.Control.MouseDefaults.prototype.destroy.apply(this,arguments);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);OpenLayers.Control.MouseDefaults.prototype.draw.apply(this,arguments);this.buttons={};var sz=new OpenLayers.Size(28,28);var centered=new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,0);this._addButton("zoombox","drag-rectangle-off.png","drag-rectangle-on.png",centered,sz,"Shift->Drag to zoom to area");centered=centered.add((this.direction=="vertical"?0:sz.w),(this.direction=="vertical"?sz.h:0));this._addButton("pan","panning-hand-off.png","panning-hand-on.png",centered,sz,"Drag the map to pan.");centered=centered.add((this.direction=="vertical"?0:sz.w),(this.direction=="vertical"?sz.h:0));this.switchModeTo("pan");return this.div;},_addButton:function(id,img,activeImg,xy,sz,title){var imgLocation=OpenLayers.Util.getImagesLocation()+img;var activeImgLocation=OpenLayers.Util.getImagesLocation()+activeImg;var btn=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MouseToolbar_"+id,xy,sz,imgLocation,"absolute");this.div.appendChild(btn);btn.imgLocation=imgLocation;btn.activeImgLocation=activeImgLocation;btn.events=new OpenLayers.Events(this,btn,null,true);btn.events.on({"mousedown":this.buttonDown,"mouseup":this.buttonUp,"dblclick":OpenLayers.Event.stop,scope:this});btn.action=id;btn.title=title;btn.alt=title;btn.map=this.map;this.buttons[id]=btn;return btn;},buttonDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
+this.buttonClicked=evt.element.action;OpenLayers.Event.stop(evt);},buttonUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
+if(this.buttonClicked!=null){if(this.buttonClicked==evt.element.action){this.switchModeTo(evt.element.action);}
+OpenLayers.Event.stop(evt);this.buttonClicked=null;}},defaultDblClick:function(evt){this.switchModeTo("pan");this.performedDrag=false;var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom+1);OpenLayers.Event.stop(evt);return false;},defaultMouseDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
+this.mouseDragStart=evt.xy.clone();this.performedDrag=false;this.startViaKeyboard=false;if(evt.shiftKey&&this.mode!="zoombox"){this.switchModeTo("zoombox");this.startViaKeyboard=true;}else if(evt.altKey&&this.mode!="measure"){this.switchModeTo("measure");}else if(!this.mode){this.switchModeTo("pan");}
+switch(this.mode){case"zoombox":this.map.div.style.cursor="crosshair";this.zoomBox=OpenLayers.Util.createDiv('zoomBox',this.mouseDragStart,null,null,"absolute","2px solid red");this.zoomBox.style.backgroundColor="white";this.zoomBox.style.filter="alpha(opacity=50)";this.zoomBox.style.opacity="0.50";this.zoomBox.style.fontSize="1px";this.zoomBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.viewPortDiv.appendChild(this.zoomBox);this.performedDrag=true;break;case"measure":var distance="";if(this.measureStart){var measureEnd=this.map.getLonLatFromViewPortPx(this.mouseDragStart);distance=OpenLayers.Util.distVincenty(this.measureStart,measureEnd);distance=Math.round(distance*100)/100;distance=distance+"km";this.measureStartBox=this.measureBox;}
+this.measureStart=this.map.getLonLatFromViewPortPx(this.mouseDragStart);;this.measureBox=OpenLayers.Util.createDiv(null,this.mouseDragStart.add(-2-parseInt(this.map.layerContainerDiv.style.left),-2-parseInt(this.map.layerContainerDiv.style.top)),null,null,"absolute");this.measureBox.style.width="4px";this.measureBox.style.height="4px";this.measureBox.style.fontSize="1px";this.measureBox.style.backgroundColor="red";this.measureBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBox);if(distance){this.measureBoxDistance=OpenLayers.Util.createDiv(null,this.mouseDragStart.add(-2-parseInt(this.map.layerContainerDiv.style.left),2-parseInt(this.map.layerContainerDiv.style.top)),null,null,"absolute");this.measureBoxDistance.innerHTML=distance;this.measureBoxDistance.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBoxDistance);this.measureDivs.push(this.measureBoxDistance);}
+this.measureBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBox);this.measureDivs.push(this.measureBox);break;default:this.map.div.style.cursor="move";break;}
+document.onselectstart=OpenLayers.Function.False;OpenLayers.Event.stop(evt);},switchModeTo:function(mode){if(mode!=this.mode){if(this.mode&&this.buttons[this.mode]){OpenLayers.Util.modifyAlphaImageDiv(this.buttons[this.mode],null,null,null,this.buttons[this.mode].imgLocation);}
+if(this.mode=="measure"&&mode!="measure"){for(var i=0,len=this.measureDivs.length;i<len;i++){if(this.measureDivs[i]){this.map.layerContainerDiv.removeChild(this.measureDivs[i]);}}
+this.measureDivs=[];this.measureStart=null;}
+this.mode=mode;if(this.buttons[mode]){OpenLayers.Util.modifyAlphaImageDiv(this.buttons[mode],null,null,null,this.buttons[mode].activeImgLocation);}
+switch(this.mode){case"zoombox":this.map.div.style.cursor="crosshair";break;default:this.map.div.style.cursor="";break;}}},leaveMode:function(){this.switchModeTo("pan");},defaultMouseMove:function(evt){if(this.mouseDragStart!=null){switch(this.mode){case"zoombox":var deltaX=Math.abs(this.mouseDragStart.x-evt.xy.x);var deltaY=Math.abs(this.mouseDragStart.y-evt.xy.y);this.zoomBox.style.width=Math.max(1,deltaX)+"px";this.zoomBox.style.height=Math.max(1,deltaY)+"px";if(evt.xy.x<this.mouseDragStart.x){this.zoomBox.style.left=evt.xy.x+"px";}
+if(evt.xy.y<this.mouseDragStart.y){this.zoomBox.style.top=evt.xy.y+"px";}
+break;default:var deltaX=this.mouseDragStart.x-evt.xy.x;var deltaY=this.mouseDragStart.y-evt.xy.y;var size=this.map.getSize();var newXY=new OpenLayers.Pixel(size.w/2+deltaX,size.h/2+deltaY);var newCenter=this.map.getLonLatFromViewPortPx(newXY);this.map.setCenter(newCenter,null,true);this.mouseDragStart=evt.xy.clone();}
+this.performedDrag=true;}},defaultMouseUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
+switch(this.mode){case"zoombox":this.zoomBoxEnd(evt);if(this.startViaKeyboard){this.leaveMode();}
+break;case"pan":if(this.performedDrag){this.map.setCenter(this.map.center);}}
+document.onselectstart=null;this.mouseDragStart=null;this.map.div.style.cursor="default";},defaultMouseOut:function(evt){if(this.mouseDragStart!=null&&OpenLayers.Util.mouseLeft(evt,this.map.div)){if(this.zoomBox){this.removeZoomBox();if(this.startViaKeyboard){this.leaveMode();}}
+this.mouseDragStart=null;this.map.div.style.cursor="default";}},defaultClick:function(evt){if(this.performedDrag){this.performedDrag=false;return false;}},CLASS_NAME:"OpenLayers.Control.MouseToolbar"});OpenLayers.Control.MouseToolbar.X=6;OpenLayers.Control.MouseToolbar.Y=300;OpenLayers.Control.NavigationHistory=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOGGLE,previous:null,previousOptions:null,next:null,nextOptions:null,limit:50,autoActivate:true,clearOnDeactivate:false,registry:null,nextStack:null,previousStack:null,listeners:null,restoring:false,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.registry=OpenLayers.Util.extend({"moveend":this.getState},this.registry);var previousOptions={trigger:OpenLayers.Function.bind(this.previousTrigger,this),displayClass:this.displayClass+" "+this.displayClass+"Previous"};OpenLayers.Util.extend(previousOptions,this.previousOptions);this.previous=new OpenLayers.Control.Button(previousOptions);var nextOptions={trigger:OpenLayers.Function.bind(this.nextTrigger,this),displayClass:this.displayClass+" "+this.displayClass+"Next"};OpenLayers.Util.extend(nextOptions,this.nextOptions);this.next=new OpenLayers.Control.Button(nextOptions);this.clear();},onPreviousChange:function(state,length){if(state&&!this.previous.active){this.previous.activate();}else if(!state&&this.previous.active){this.previous.deactivate();}},onNextChange:function(state,length){if(state&&!this.next.active){this.next.activate();}else if(!state&&this.next.active){this.next.deactivate();}},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this);this.previous.destroy();this.next.destroy();this.deactivate();for(var prop in this){this[prop]=null;}},setMap:function(map){this.map=map;this.next.setMap(map);this.previous.setMap(map);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.next.draw();this.previous.draw();},previousTrigger:function(){var current=this.previousStack.shift();var state=this.previousStack.shift();if(state!=undefined){this.nextStack.unshift(current);this.previousStack.unshift(state);this.restoring=true;this.restore(state);this.restoring=false;this.onNextChange(this.nextStack[0],this.nextStack.length);this.onPreviousChange(this.previousStack[1],this.previousStack.length-1);}else{this.previousStack.unshift(current);}
+return state;},nextTrigger:function(){var state=this.nextStack.shift();if(state!=undefined){this.previousStack.unshift(state);this.restoring=true;this.restore(state);this.restoring=false;this.onNextChange(this.nextStack[0],this.nextStack.length);this.onPreviousChange(this.previousStack[1],this.previousStack.length-1);}
+return state;},clear:function(){this.previousStack=[];this.previous.deactivate();this.nextStack=[];this.next.deactivate();},getState:function(){return{center:this.map.getCenter(),resolution:this.map.getResolution(),projection:this.map.getProjectionObject(),units:this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units};},restore:function(state){var center,zoom;if(this.map.getProjectionObject()==state.projection){zoom=this.map.getZoomForResolution(state.resolution);center=state.center;}else{center=state.center.clone();center.transform(state.projection,this.map.getProjectionObject());var sourceUnits=state.units;var targetUnits=this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units;var resolutionFactor=sourceUnits&&targetUnits?OpenLayers.INCHES_PER_UNIT[sourceUnits]/OpenLayers.INCHES_PER_UNIT[targetUnits]:1;zoom=this.map.getZoomForResolution(resolutionFactor*state.resolution);}
+this.map.setCenter(center,zoom);},setListeners:function(){this.listeners={};for(var type in this.registry){this.listeners[type]=OpenLayers.Function.bind(function(){if(!this.restoring){var state=this.registry[type].apply(this,arguments);this.previousStack.unshift(state);if(this.previousStack.length>1){this.onPreviousChange(this.previousStack[1],this.previousStack.length-1);}
+if(this.previousStack.length>(this.limit+1)){this.previousStack.pop();}
+if(this.nextStack.length>0){this.nextStack=[];this.onNextChange(null,0);}}
+return true;},this);}},activate:function(){var activated=false;if(this.map){if(OpenLayers.Control.prototype.activate.apply(this)){if(this.listeners==null){this.setListeners();}
+for(var type in this.listeners){this.map.events.register(type,this,this.listeners[type]);}
+activated=true;if(this.previousStack.length==0){this.initStack();}}}
+return activated;},initStack:function(){if(this.map.getCenter()){this.listeners.moveend();}},deactivate:function(){var deactivated=false;if(this.map){if(OpenLayers.Control.prototype.deactivate.apply(this)){for(var type in this.listeners){this.map.events.unregister(type,this,this.listeners[type]);}
+if(this.clearOnDeactivate){this.clear();}
+deactivated=true;}}
+return deactivated;},CLASS_NAME:"OpenLayers.Control.NavigationHistory"});OpenLayers.Control.PanPanel=OpenLayers.Class(OpenLayers.Control.Panel,{slideFactor:50,initialize:function(options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.Pan(OpenLayers.Control.Pan.NORTH,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.SOUTH,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.EAST,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.WEST,{slideFactor:this.slideFactor})]);},CLASS_NAME:"OpenLayers.Control.PanPanel"});OpenLayers.Control.PanZoomBar=OpenLayers.Class(OpenLayers.Control.PanZoom,{zoomStopWidth:18,zoomStopHeight:11,slider:null,sliderEvents:null,zoombarDiv:null,divEvents:null,zoomWorldIcon:false,forceFixedZoomLevel:false,mouseDragStart:null,zoomStart:null,initialize:function(){OpenLayers.Control.PanZoom.prototype.initialize.apply(this,arguments);},destroy:function(){this._removeZoomBar();this.map.events.un({"changebaselayer":this.redraw,scope:this});OpenLayers.Control.PanZoom.prototype.destroy.apply(this,arguments);delete this.mouseDragStart;delete this.zoomStart;},setMap:function(map){OpenLayers.Control.PanZoom.prototype.setMap.apply(this,arguments);this.map.events.register("changebaselayer",this,this.redraw);},redraw:function(){if(this.div!=null){this.removeButtons();this._removeZoomBar();}
+this.draw();},draw:function(px){OpenLayers.Control.prototype.draw.apply(this,arguments);px=this.position.clone();this.buttons=[];var sz=new OpenLayers.Size(18,18);var centered=new OpenLayers.Pixel(px.x+sz.w/2,px.y);var wposition=sz.w;if(this.zoomWorldIcon){centered=new OpenLayers.Pixel(px.x+sz.w,px.y);}
+this._addButton("panup","north-mini.png",centered,sz);px.y=centered.y+sz.h;this._addButton("panleft","west-mini.png",px,sz);if(this.zoomWorldIcon){this._addButton("zoomworld","zoom-world-mini.png",px.add(sz.w,0),sz);wposition*=2;}
+this._addButton("panright","east-mini.png",px.add(wposition,0),sz);this._addButton("pandown","south-mini.png",centered.add(0,sz.h*2),sz);this._addButton("zoomin","zoom-plus-mini.png",centered.add(0,sz.h*3+5),sz);centered=this._addZoomBar(centered.add(0,sz.h*4+5));this._addButton("zoomout","zoom-minus-mini.png",centered,sz);return this.div;},_addZoomBar:function(centered){var imgLocation=OpenLayers.Util.getImagesLocation();var id=this.id+"_"+this.map.id;var zoomsToEnd=this.map.getNumZoomLevels()-1-this.map.getZoom();var slider=OpenLayers.Util.createAlphaImageDiv(id,centered.add(-1,zoomsToEnd*this.zoomStopHeight),new OpenLayers.Size(20,9),imgLocation+"slider.png","absolute");this.slider=slider;this.sliderEvents=new OpenLayers.Events(this,slider,null,true,{includeXY:true});this.sliderEvents.on({"mousedown":this.zoomBarDown,"mousemove":this.zoomBarDrag,"mouseup":this.zoomBarUp,"dblclick":this.doubleClick,"click":this.doubleClick});var sz=new OpenLayers.Size();sz.h=this.zoomStopHeight*this.map.getNumZoomLevels();sz.w=this.zoomStopWidth;var div=null;if(OpenLayers.Util.alphaHack()){var id=this.id+"_"+this.map.id;div=OpenLayers.Util.createAlphaImageDiv(id,centered,new OpenLayers.Size(sz.w,this.zoomStopHeight),imgLocation+"zoombar.png","absolute",null,"crop");div.style.height=sz.h+"px";}else{div=OpenLayers.Util.createDiv('OpenLayers_Control_PanZoomBar_Zoombar'+this.map.id,centered,sz,imgLocation+"zoombar.png");}
+this.zoombarDiv=div;this.divEvents=new OpenLayers.Events(this,div,null,true,{includeXY:true});this.divEvents.on({"mousedown":this.divClick,"mousemove":this.passEventToSlider,"dblclick":this.doubleClick,"click":this.doubleClick});this.div.appendChild(div);this.startTop=parseInt(div.style.top);this.div.appendChild(slider);this.map.events.register("zoomend",this,this.moveZoomBar);centered=centered.add(0,this.zoomStopHeight*this.map.getNumZoomLevels());return centered;},_removeZoomBar:function(){this.sliderEvents.un({"mousedown":this.zoomBarDown,"mousemove":this.zoomBarDrag,"mouseup":this.zoomBarUp,"dblclick":this.doubleClick,"click":this.doubleClick});this.sliderEvents.destroy();this.divEvents.un({"mousedown":this.divClick,"mousemove":this.passEventToSlider,"dblclick":this.doubleClick,"click":this.doubleClick});this.divEvents.destroy();this.div.removeChild(this.zoombarDiv);this.zoombarDiv=null;this.div.removeChild(this.slider);this.slider=null;this.map.events.unregister("zoomend",this,this.moveZoomBar);},passEventToSlider:function(evt){this.sliderEvents.handleBrowserEvent(evt);},divClick:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
+var y=evt.xy.y;var top=OpenLayers.Util.pagePosition(evt.object)[1];var levels=(y-top)/this.zoomStopHeight;if(this.forceFixedZoomLevel||!this.map.fractionalZoom){levels=Math.floor(levels);}
+var zoom=(this.map.getNumZoomLevels()-1)-levels;zoom=Math.min(Math.max(zoom,0),this.map.getNumZoomLevels()-1);this.map.zoomTo(zoom);OpenLayers.Event.stop(evt);},zoomBarDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
+this.map.events.on({"mousemove":this.passEventToSlider,"mouseup":this.passEventToSlider,scope:this});this.mouseDragStart=evt.xy.clone();this.zoomStart=evt.xy.clone();this.div.style.cursor="move";this.zoombarDiv.offsets=null;OpenLayers.Event.stop(evt);},zoomBarDrag:function(evt){if(this.mouseDragStart!=null){var deltaY=this.mouseDragStart.y-evt.xy.y;var offsets=OpenLayers.Util.pagePosition(this.zoombarDiv);if((evt.clientY-offsets[1])>0&&(evt.clientY-offsets[1])<parseInt(this.zoombarDiv.style.height)-2){var newTop=parseInt(this.slider.style.top)-deltaY;this.slider.style.top=newTop+"px";this.mouseDragStart=evt.xy.clone();}
+OpenLayers.Event.stop(evt);}},zoomBarUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
+if(this.mouseDragStart){this.div.style.cursor="";this.map.events.un({"mouseup":this.passEventToSlider,"mousemove":this.passEventToSlider,scope:this});var deltaY=this.zoomStart.y-evt.xy.y;var zoomLevel=this.map.zoom;if(!this.forceFixedZoomLevel&&this.map.fractionalZoom){zoomLevel+=deltaY/this.zoomStopHeight;zoomLevel=Math.min(Math.max(zoomLevel,0),this.map.getNumZoomLevels()-1);}else{zoomLevel+=Math.round(deltaY/this.zoomStopHeight);}
+this.map.zoomTo(zoomLevel);this.mouseDragStart=null;this.zoomStart=null;OpenLayers.Event.stop(evt);}},moveZoomBar:function(){var newTop=((this.map.getNumZoomLevels()-1)-this.map.getZoom())*this.zoomStopHeight+this.startTop+1;this.slider.style.top=newTop+"px";},CLASS_NAME:"OpenLayers.Control.PanZoomBar"});OpenLayers.Control.Permalink=OpenLayers.Class(OpenLayers.Control,{argParserClass:OpenLayers.Control.ArgParser,element:null,base:'',displayProjection:null,initialize:function(element,base,options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.element=OpenLayers.Util.getElement(element);this.base=base||document.location.href;},destroy:function(){if(this.element.parentNode==this.div){this.div.removeChild(this.element);}
+this.element=null;this.map.events.unregister('moveend',this,this.updateLink);OpenLayers.Control.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Control.prototype.setMap.apply(this,arguments);for(var i=0,len=this.map.controls.length;i<len;i++){var control=this.map.controls[i];if(control.CLASS_NAME==this.argParserClass.CLASS_NAME){if(control.displayProjection!=this.displayProjection){this.displayProjection=control.displayProjection;}
+break;}}
+if(i==this.map.controls.length){this.map.addControl(new this.argParserClass({'displayProjection':this.displayProjection}));}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.element){this.div.className=this.displayClass;this.element=document.createElement("a");this.element.innerHTML=OpenLayers.i18n("permalink");this.element.href="";this.div.appendChild(this.element);}
+this.map.events.on({'moveend':this.updateLink,'changelayer':this.updateLink,'changebaselayer':this.updateLink,scope:this});this.updateLink();return this.div;},updateLink:function(){var href=this.base;if(href.indexOf('?')!=-1){href=href.substring(0,href.indexOf('?'));}
+href+='?'+OpenLayers.Util.getParameterString(this.createParams());this.element.href=href;},createParams:function(center,zoom,layers){center=center||this.map.getCenter();var params=OpenLayers.Util.getParameters(this.base);if(center){params.zoom=zoom||this.map.getZoom();var lat=center.lat;var lon=center.lon;if(this.displayProjection){var mapPosition=OpenLayers.Projection.transform({x:lon,y:lat},this.map.getProjectionObject(),this.displayProjection);lon=mapPosition.x;lat=mapPosition.y;}
+params.lat=Math.round(lat*100000)/100000;params.lon=Math.round(lon*100000)/100000;layers=layers||this.map.layers;params.layers='';for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];if(layer.isBaseLayer){params.layers+=(layer==this.map.baseLayer)?"B":"0";}else{params.layers+=(layer.getVisibility())?"T":"F";}}}
+return params;},CLASS_NAME:"OpenLayers.Control.Permalink"});OpenLayers.Control.ZoomPanel=OpenLayers.Class(OpenLayers.Control.Panel,{initialize:function(options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.ZoomIn(),new OpenLayers.Control.ZoomToMaxExtent(),new OpenLayers.Control.ZoomOut()]);},CLASS_NAME:"OpenLayers.Control.ZoomPanel"});OpenLayers.Format.CSWGetDomain=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Format.CSWGetDomain.DEFAULTS);var cls=OpenLayers.Format.CSWGetDomain["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported CSWGetDomain version: "+options.version;}
+return new cls(options);};OpenLayers.Format.CSWGetDomain.DEFAULTS={"version":"2.0.2"};OpenLayers.Format.CSWGetRecords=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Format.CSWGetRecords.DEFAULTS);var cls=OpenLayers.Format.CSWGetRecords["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported CSWGetRecords version: "+options.version;}
+return new cls(options);};OpenLayers.Format.CSWGetRecords.DEFAULTS={"version":"2.0.2"};OpenLayers.Format.JSON=OpenLayers.Class(OpenLayers.Format,{indent:"    ",space:" ",newline:"\n",level:0,pretty:false,initialize:function(options){OpenLayers.Format.prototype.initialize.apply(this,[options]);},read:function(json,filter){try{if(/^[\],:{}\s]*$/.test(json.replace(/\\["\\\/bfnrtu]/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){var object=eval('('+json+')');if(typeof filter==='function'){function walk(k,v){if(v&&typeof v==='object'){for(var i in v){if(v.hasOwnProperty(i)){v[i]=walk(i,v[i]);}}}
+return filter(k,v);}
+object=walk('',object);}
+if(this.keepData){this.data=object;}
+return object;}}catch(e){}
+return null;},write:function(value,pretty){this.pretty=!!pretty;var json=null;var type=typeof value;if(this.serialize[type]){try{json=this.serialize[type].apply(this,[value]);}catch(err){OpenLayers.Console.error("Trouble serializing: "+err);}}
+return json;},writeIndent:function(){var pieces=[];if(this.pretty){for(var i=0;i<this.level;++i){pieces.push(this.indent);}}
+return pieces.join('');},writeNewline:function(){return(this.pretty)?this.newline:'';},writeSpace:function(){return(this.pretty)?this.space:'';},serialize:{'object':function(object){if(object==null){return"null";}
+if(object.constructor==Date){return this.serialize.date.apply(this,[object]);}
+if(object.constructor==Array){return this.serialize.array.apply(this,[object]);}
+var pieces=['{'];this.level+=1;var key,keyJSON,valueJSON;var addComma=false;for(key in object){if(object.hasOwnProperty(key)){keyJSON=OpenLayers.Format.JSON.prototype.write.apply(this,[key,this.pretty]);valueJSON=OpenLayers.Format.JSON.prototype.write.apply(this,[object[key],this.pretty]);if(keyJSON!=null&&valueJSON!=null){if(addComma){pieces.push(',');}
+pieces.push(this.writeNewline(),this.writeIndent(),keyJSON,':',this.writeSpace(),valueJSON);addComma=true;}}}
+this.level-=1;pieces.push(this.writeNewline(),this.writeIndent(),'}');return pieces.join('');},'array':function(array){var json;var pieces=['['];this.level+=1;for(var i=0,len=array.length;i<len;++i){json=OpenLayers.Format.JSON.prototype.write.apply(this,[array[i],this.pretty]);if(json!=null){if(i>0){pieces.push(',');}
+pieces.push(this.writeNewline(),this.writeIndent(),json);}}
+this.level-=1;pieces.push(this.writeNewline(),this.writeIndent(),']');return pieces.join('');},'string':function(string){var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};if(/["\\\x00-\x1f]/.test(string)){return'"'+string.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];if(c){return c;}
+c=b.charCodeAt();return'\\u00'+
+Math.floor(c/16).toString(16)+
+(c%16).toString(16);})+'"';}
+return'"'+string+'"';},'number':function(number){return isFinite(number)?String(number):"null";},'boolean':function(bool){return String(bool);},'date':function(date){function format(number){return(number<10)?'0'+number:number;}
+return'"'+date.getFullYear()+'-'+
+format(date.getMonth()+1)+'-'+
+format(date.getDate())+'T'+
+format(date.getHours())+':'+
+format(date.getMinutes())+':'+
+format(date.getSeconds())+'"';}},CLASS_NAME:"OpenLayers.Format.JSON"});OpenLayers.Format.WFST=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Format.WFST.DEFAULTS);var cls=OpenLayers.Format.WFST["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported WFST version: "+options.version;}
+return new cls(options);};OpenLayers.Format.WFST.DEFAULTS={"version":"1.0.0"};OpenLayers.Format.XML=OpenLayers.Class(OpenLayers.Format,{namespaces:null,namespaceAlias:null,defaultPrefix:null,readers:{},writers:{},xmldom:null,initialize:function(options){if(window.ActiveXObject){this.xmldom=new ActiveXObject("Microsoft.XMLDOM");}
+OpenLayers.Format.prototype.initialize.apply(this,[options]);this.namespaces=OpenLayers.Util.extend({},this.namespaces);this.namespaceAlias={};for(var alias in this.namespaces){this.namespaceAlias[this.namespaces[alias]]=alias;}},destroy:function(){this.xmldom=null;OpenLayers.Format.prototype.destroy.apply(this,arguments);},setNamespace:function(alias,uri){this.namespaces[alias]=uri;this.namespaceAlias[uri]=alias;},read:function(text){var index=text.indexOf('<');if(index>0){text=text.substring(index);}
+var node=OpenLayers.Util.Try(OpenLayers.Function.bind((function(){var xmldom;if(window.ActiveXObject&&!this.xmldom){xmldom=new ActiveXObject("Microsoft.XMLDOM");}else{xmldom=this.xmldom;}
+xmldom.loadXML(text);return xmldom;}),this),function(){return new DOMParser().parseFromString(text,'text/xml');},function(){var req=new XMLHttpRequest();req.open("GET","data:"+"text/xml"+";charset=utf-8,"+encodeURIComponent(text),false);if(req.overrideMimeType){req.overrideMimeType("text/xml");}
+req.send(null);return req.responseXML;});if(this.keepData){this.data=node;}
+return node;},write:function(node){var data;if(this.xmldom){data=node.xml;}else{var serializer=new XMLSerializer();if(node.nodeType==1){var doc=document.implementation.createDocument("","",null);if(doc.importNode){node=doc.importNode(node,true);}
+doc.appendChild(node);data=serializer.serializeToString(doc);}else{data=serializer.serializeToString(node);}}
+return data;},createElementNS:function(uri,name){var element;if(this.xmldom){if(typeof uri=="string"){element=this.xmldom.createNode(1,name,uri);}else{element=this.xmldom.createNode(1,name,"");}}else{element=document.createElementNS(uri,name);}
+return element;},createTextNode:function(text){var node;if(typeof text!=="string"){text=String(text);}
+if(this.xmldom){node=this.xmldom.createTextNode(text);}else{node=document.createTextNode(text);}
+return node;},getElementsByTagNameNS:function(node,uri,name){var elements=[];if(node.getElementsByTagNameNS){elements=node.getElementsByTagNameNS(uri,name);}else{var allNodes=node.getElementsByTagName("*");var potentialNode,fullName;for(var i=0,len=allNodes.length;i<len;++i){potentialNode=allNodes[i];fullName=(potentialNode.prefix)?(potentialNode.prefix+":"+name):name;if((name=="*")||(fullName==potentialNode.nodeName)){if((uri=="*")||(uri==potentialNode.namespaceURI)){elements.push(potentialNode);}}}}
+return elements;},getAttributeNodeNS:function(node,uri,name){var attributeNode=null;if(node.getAttributeNodeNS){attributeNode=node.getAttributeNodeNS(uri,name);}else{var attributes=node.attributes;var potentialNode,fullName;for(var i=0,len=attributes.length;i<len;++i){potentialNode=attributes[i];if(potentialNode.namespaceURI==uri){fullName=(potentialNode.prefix)?(potentialNode.prefix+":"+name):name;if(fullName==potentialNode.nodeName){attributeNode=potentialNode;break;}}}}
+return attributeNode;},getAttributeNS:function(node,uri,name){var attributeValue="";if(node.getAttributeNS){attributeValue=node.getAttributeNS(uri,name)||"";}else{var attributeNode=this.getAttributeNodeNS(node,uri,name);if(attributeNode){attributeValue=attributeNode.nodeValue;}}
+return attributeValue;},getChildValue:function(node,def){var value=def||"";if(node){for(var child=node.firstChild;child;child=child.nextSibling){switch(child.nodeType){case 3:case 4:value+=child.nodeValue;}}}
+return value;},concatChildValues:function(node,def){var value="";var child=node.firstChild;var childValue;while(child){childValue=child.nodeValue;if(childValue){value+=childValue;}
+child=child.nextSibling;}
+if(value==""&&def!=undefined){value=def;}
+return value;},isSimpleContent:function(node){var simple=true;for(var child=node.firstChild;child;child=child.nextSibling){if(child.nodeType===1){simple=false;break;}}
+return simple;},contentType:function(node){var simple=false,complex=false;var type=OpenLayers.Format.XML.CONTENT_TYPE.EMPTY;for(var child=node.firstChild;child;child=child.nextSibling){switch(child.nodeType){case 1:complex=true;break;case 8:break;default:simple=true;}
+if(complex&&simple){break;}}
+if(complex&&simple){type=OpenLayers.Format.XML.CONTENT_TYPE.MIXED;}else if(complex){return OpenLayers.Format.XML.CONTENT_TYPE.COMPLEX;}else if(simple){return OpenLayers.Format.XML.CONTENT_TYPE.SIMPLE;}
+return type;},hasAttributeNS:function(node,uri,name){var found=false;if(node.hasAttributeNS){found=node.hasAttributeNS(uri,name);}else{found=!!this.getAttributeNodeNS(node,uri,name);}
+return found;},setAttributeNS:function(node,uri,name,value){if(node.setAttributeNS){node.setAttributeNS(uri,name,value);}else{if(this.xmldom){if(uri){var attribute=node.ownerDocument.createNode(2,name,uri);attribute.nodeValue=value;node.setAttributeNode(attribute);}else{node.setAttribute(name,value);}}else{throw"setAttributeNS not implemented";}}},createElementNSPlus:function(name,options){options=options||{};var uri=options.uri||this.namespaces[options.prefix];if(!uri){var loc=name.indexOf(":");uri=this.namespaces[name.substring(0,loc)];}
+if(!uri){uri=this.namespaces[this.defaultPrefix];}
+var node=this.createElementNS(uri,name);if(options.attributes){this.setAttributes(node,options.attributes);}
+var value=options.value;if(value!=null){node.appendChild(this.createTextNode(value));}
+return node;},setAttributes:function(node,obj){var value,uri;for(var name in obj){if(obj[name]!=null&&obj[name].toString){value=obj[name].toString();uri=this.namespaces[name.substring(0,name.indexOf(":"))]||null;this.setAttributeNS(node,uri,name,value);}}},readNode:function(node,obj){if(!obj){obj={};}
+var group=this.readers[node.namespaceURI?this.namespaceAlias[node.namespaceURI]:this.defaultPrefix];if(group){var local=node.localName||node.nodeName.split(":").pop();var reader=group[local]||group["*"];if(reader){reader.apply(this,[node,obj]);}}
+return obj;},readChildNodes:function(node,obj){if(!obj){obj={};}
+var children=node.childNodes;var child;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){this.readNode(child,obj);}}
+return obj;},writeNode:function(name,obj,parent){var prefix,local;var split=name.indexOf(":");if(split>0){prefix=name.substring(0,split);local=name.substring(split+1);}else{if(parent){prefix=this.namespaceAlias[parent.namespaceURI];}else{prefix=this.defaultPrefix;}
+local=name;}
+var child=this.writers[prefix][local].apply(this,[obj]);if(parent){parent.appendChild(child);}
+return child;},getChildEl:function(node,name,uri){return node&&this.getThisOrNextEl(node.firstChild,name,uri);},getNextEl:function(node,name,uri){return node&&this.getThisOrNextEl(node.nextSibling,name,uri);},getThisOrNextEl:function(node,name,uri){outer:for(var sibling=node;sibling;sibling=sibling.nextSibling){switch(sibling.nodeType){case 1:if((!name||name===(sibling.localName||sibling.nodeName.split(":").pop()))&&(!uri||uri===sibling.namespaceURI)){break outer;}
+sibling=null;break outer;case 3:if(/^\s*$/.test(sibling.nodeValue)){break;}
+case 4:case 6:case 12:case 10:case 11:sibling=null;break outer;}}
+return sibling||null;},lookupNamespaceURI:function(node,prefix){var uri=null;if(node){if(node.lookupNamespaceURI){uri=node.lookupNamespaceURI(prefix);}else{outer:switch(node.nodeType){case 1:if(node.namespaceURI!==null&&node.prefix===prefix){uri=node.namespaceURI;break outer;}
+var len=node.attributes.length;if(len){var attr;for(var i=0;i<len;++i){attr=node.attributes[i];if(attr.prefix==="xmlns"&&attr.name==="xmlns:"+prefix){uri=attr.value||null;break outer;}else if(attr.name==="xmlns"&&prefix===null){uri=attr.value||null;break outer;}}}
+uri=this.lookupNamespaceURI(node.parentNode,prefix);break outer;case 2:uri=this.lookupNamespaceURI(node.ownerElement,prefix);break outer;case 9:uri=this.lookupNamespaceURI(node.documentElement,prefix);break outer;case 6:case 12:case 10:case 11:break outer;default:uri=this.lookupNamespaceURI(node.parentNode,prefix);break outer;}}}
+return uri;},CLASS_NAME:"OpenLayers.Format.XML"});OpenLayers.Format.XML.CONTENT_TYPE={EMPTY:0,SIMPLE:1,COMPLEX:2,MIXED:3};OpenLayers.Format.XML.lookupNamespaceURI=OpenLayers.Function.bind(OpenLayers.Format.XML.prototype.lookupNamespaceURI,OpenLayers.Format.XML.prototype);OpenLayers.Handler=OpenLayers.Class({id:null,control:null,map:null,keyMask:null,active:false,evt:null,initialize:function(control,callbacks,options){OpenLayers.Util.extend(this,options);this.control=control;this.callbacks=callbacks;var map=this.map||control.map;if(map){this.setMap(map);}
+this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},setMap:function(map){this.map=map;},checkModifiers:function(evt){if(this.keyMask==null){return true;}
+var keyModifiers=(evt.shiftKey?OpenLayers.Handler.MOD_SHIFT:0)|(evt.ctrlKey?OpenLayers.Handler.MOD_CTRL:0)|(evt.altKey?OpenLayers.Handler.MOD_ALT:0);return(keyModifiers==this.keyMask);},activate:function(){if(this.active){return false;}
+var events=OpenLayers.Events.prototype.BROWSER_EVENTS;for(var i=0,len=events.length;i<len;i++){if(this[events[i]]){this.register(events[i],this[events[i]]);}}
+this.active=true;return true;},deactivate:function(){if(!this.active){return false;}
+var events=OpenLayers.Events.prototype.BROWSER_EVENTS;for(var i=0,len=events.length;i<len;i++){if(this[events[i]]){this.unregister(events[i],this[events[i]]);}}
+this.active=false;return true;},callback:function(name,args){if(name&&this.callbacks[name]){this.callbacks[name].apply(this.control,args);}},register:function(name,method){this.map.events.registerPriority(name,this,method);this.map.events.registerPriority(name,this,this.setEvent);},unregister:function(name,method){this.map.events.unregister(name,this,method);this.map.events.unregister(name,this,this.setEvent);},setEvent:function(evt){this.evt=evt;return true;},destroy:function(){this.deactivate();this.control=this.map=null;},CLASS_NAME:"OpenLayers.Handler"});OpenLayers.Handler.MOD_NONE=0;OpenLayers.Handler.MOD_SHIFT=1;OpenLayers.Handler.MOD_CTRL=2;OpenLayers.Handler.MOD_ALT=4;OpenLayers.Map=OpenLayers.Class({Z_INDEX_BASE:{BaseLayer:100,Overlay:325,Feature:725,Popup:750,Control:1000},EVENT_TYPES:["preaddlayer","addlayer","removelayer","changelayer","movestart","move","moveend","zoomend","popupopen","popupclose","addmarker","removemarker","clearmarkers","mouseover","mouseout","mousemove","dragstart","drag","dragend","changebaselayer"],id:null,fractionalZoom:false,events:null,allOverlays:false,div:null,dragging:false,size:null,viewPortDiv:null,layerContainerOrigin:null,layerContainerDiv:null,layers:null,controls:null,popups:null,baseLayer:null,center:null,resolution:null,zoom:0,panRatio:1.5,viewRequestID:0,tileSize:null,projection:"EPSG:4326",units:'degrees',resolutions:null,maxResolution:1.40625,minResolution:null,maxScale:null,minScale:null,maxExtent:null,minExtent:null,restrictedExtent:null,numZoomLevels:16,theme:null,displayProjection:null,fallThrough:true,panTween:null,eventListeners:null,panMethod:OpenLayers.Easing.Expo.easeOut,panDuration:50,paddingForPopups:null,initialize:function(div,options){if(arguments.length===1&&typeof div==="object"){options=div;div=options&&options.div;}
+this.tileSize=new OpenLayers.Size(OpenLayers.Map.TILE_WIDTH,OpenLayers.Map.TILE_HEIGHT);this.maxExtent=new OpenLayers.Bounds(-180,-90,180,90);this.paddingForPopups=new OpenLayers.Bounds(15,15,15,15);this.theme=OpenLayers._getScriptLocation()?OpenLayers._getScriptLocation()+'theme/default/style.css':null;OpenLayers.Util.extend(this,options);this.layers=[];this.id=OpenLayers.Util.createUniqueID("OpenLayers.Map_");this.div=OpenLayers.Util.getElement(div);if(!this.div){this.div=document.createElement("div");this.div.style.height="1px";this.div.style.width="1px";}
+OpenLayers.Element.addClass(this.div,'olMap');var id=this.id+"_OpenLayers_ViewPort";this.viewPortDiv=OpenLayers.Util.createDiv(id,null,null,null,"relative",null,"hidden");this.viewPortDiv.style.width="100%";this.viewPortDiv.style.height="100%";this.viewPortDiv.className="olMapViewport";this.div.appendChild(this.viewPortDiv);id=this.id+"_OpenLayers_Container";this.layerContainerDiv=OpenLayers.Util.createDiv(id);this.layerContainerDiv.style.zIndex=this.Z_INDEX_BASE['Popup']-1;this.viewPortDiv.appendChild(this.layerContainerDiv);this.events=new OpenLayers.Events(this,this.div,this.EVENT_TYPES,this.fallThrough,{includeXY:true});this.updateSize();if(this.eventListeners instanceof Object){this.events.on(this.eventListeners);}
+this.events.register("movestart",this,this.updateSize);if(OpenLayers.String.contains(navigator.appName,"Microsoft")){this.events.register("resize",this,this.updateSize);}else{this.updateSizeDestroy=OpenLayers.Function.bind(this.updateSize,this);OpenLayers.Event.observe(window,'resize',this.updateSizeDestroy);}
+if(this.theme){var addNode=true;var nodes=document.getElementsByTagName('link');for(var i=0,len=nodes.length;i<len;++i){if(OpenLayers.Util.isEquivalentUrl(nodes.item(i).href,this.theme)){addNode=false;break;}}
+if(addNode){var cssNode=document.createElement('link');cssNode.setAttribute('rel','stylesheet');cssNode.setAttribute('type','text/css');cssNode.setAttribute('href',this.theme);document.getElementsByTagName('head')[0].appendChild(cssNode);}}
+if(this.controls==null){if(OpenLayers.Control!=null){this.controls=[new OpenLayers.Control.Navigation(),new OpenLayers.Control.PanZoom(),new OpenLayers.Control.ArgParser(),new OpenLayers.Control.Attribution()];}else{this.controls=[];}}
+for(var i=0,len=this.controls.length;i<len;i++){this.addControlToMap(this.controls[i]);}
+this.popups=[];this.unloadDestroy=OpenLayers.Function.bind(this.destroy,this);OpenLayers.Event.observe(window,'unload',this.unloadDestroy);if(options&&options.layers){this.addLayers(options.layers);if(options.center){this.setCenter(options.center,options.zoom);}}},render:function(div){this.div=OpenLayers.Util.getElement(div);OpenLayers.Element.addClass(this.div,'olMap');this.events.attachToElement(this.div);this.viewPortDiv.parentNode.removeChild(this.viewPortDiv);this.div.appendChild(this.viewPortDiv);this.updateSize();},unloadDestroy:null,updateSizeDestroy:null,destroy:function(){if(!this.unloadDestroy){return false;}
+if(this.panTween){this.panTween.stop();this.panTween=null;}
+OpenLayers.Event.stopObserving(window,'unload',this.unloadDestroy);this.unloadDestroy=null;if(this.updateSizeDestroy){OpenLayers.Event.stopObserving(window,'resize',this.updateSizeDestroy);}else{this.events.unregister("resize",this,this.updateSize);}
+this.paddingForPopups=null;if(this.controls!=null){for(var i=this.controls.length-1;i>=0;--i){this.controls[i].destroy();}
+this.controls=null;}
+if(this.layers!=null){for(var i=this.layers.length-1;i>=0;--i){this.layers[i].destroy(false);}
+this.layers=null;}
+if(this.viewPortDiv){this.div.removeChild(this.viewPortDiv);}
+this.viewPortDiv=null;if(this.eventListeners){this.events.un(this.eventListeners);this.eventListeners=null;}
+this.events.destroy();this.events=null;},setOptions:function(options){OpenLayers.Util.extend(this,options);},getTileSize:function(){return this.tileSize;},getBy:function(array,property,match){var test=(typeof match.test=="function");var found=OpenLayers.Array.filter(this[array],function(item){return item[property]==match||(test&&match.test(item[property]));});return found;},getLayersBy:function(property,match){return this.getBy("layers",property,match);},getLayersByName:function(match){return this.getLayersBy("name",match);},getLayersByClass:function(match){return this.getLayersBy("CLASS_NAME",match);},getControlsBy:function(property,match){return this.getBy("controls",property,match);},getControlsByClass:function(match){return this.getControlsBy("CLASS_NAME",match);},getLayer:function(id){var foundLayer=null;for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer.id==id){foundLayer=layer;break;}}
+return foundLayer;},setLayerZIndex:function(layer,zIdx){layer.setZIndex(this.Z_INDEX_BASE[layer.isBaseLayer?'BaseLayer':'Overlay']
++zIdx*5);},resetLayersZIndex:function(){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];this.setLayerZIndex(layer,i);}},addLayer:function(layer){for(var i=0,len=this.layers.length;i<len;i++){if(this.layers[i]==layer){var msg=OpenLayers.i18n('layerAlreadyAdded',{'layerName':layer.name});OpenLayers.Console.warn(msg);return false;}}
+if(this.allOverlays){layer.isBaseLayer=false;}
+if(this.events.triggerEvent("preaddlayer",{layer:layer})===false){return;}
+layer.div.className="olLayerDiv";layer.div.style.overflow="";this.setLayerZIndex(layer,this.layers.length);if(layer.isFixed){this.viewPortDiv.appendChild(layer.div);}else{this.layerContainerDiv.appendChild(layer.div);}
+this.layers.push(layer);layer.setMap(this);if(layer.isBaseLayer||(this.allOverlays&&!this.baseLayer)){if(this.baseLayer==null){this.setBaseLayer(layer);}else{layer.setVisibility(false);}}else{layer.redraw();}
+this.events.triggerEvent("addlayer",{layer:layer});layer.afterAdd();},addLayers:function(layers){for(var i=0,len=layers.length;i<len;i++){this.addLayer(layers[i]);}},removeLayer:function(layer,setNewBaseLayer){if(setNewBaseLayer==null){setNewBaseLayer=true;}
+if(layer.isFixed){this.viewPortDiv.removeChild(layer.div);}else{this.layerContainerDiv.removeChild(layer.div);}
+OpenLayers.Util.removeItem(this.layers,layer);layer.removeMap(this);layer.map=null;if(this.baseLayer==layer){this.baseLayer=null;if(setNewBaseLayer){for(var i=0,len=this.layers.length;i<len;i++){var iLayer=this.layers[i];if(iLayer.isBaseLayer||this.allOverlays){this.setBaseLayer(iLayer);break;}}}}
+this.resetLayersZIndex();this.events.triggerEvent("removelayer",{layer:layer});},getNumLayers:function(){return this.layers.length;},getLayerIndex:function(layer){return OpenLayers.Util.indexOf(this.layers,layer);},setLayerIndex:function(layer,idx){var base=this.getLayerIndex(layer);if(idx<0){idx=0;}else if(idx>this.layers.length){idx=this.layers.length;}
+if(base!=idx){this.layers.splice(base,1);this.layers.splice(idx,0,layer);for(var i=0,len=this.layers.length;i<len;i++){this.setLayerZIndex(this.layers[i],i);}
+this.events.triggerEvent("changelayer",{layer:layer,property:"order"});if(this.allOverlays){if(idx===0){this.setBaseLayer(layer);}else if(this.baseLayer!==this.layers[0]){this.setBaseLayer(this.layers[0]);}}}},raiseLayer:function(layer,delta){var idx=this.getLayerIndex(layer)+delta;this.setLayerIndex(layer,idx);},setBaseLayer:function(newBaseLayer){if(newBaseLayer!=this.baseLayer){if(OpenLayers.Util.indexOf(this.layers,newBaseLayer)!=-1){var center=this.getCenter();var newResolution=OpenLayers.Util.getResolutionFromScale(this.getScale(),newBaseLayer.units);if(this.baseLayer!=null&&!this.allOverlays){this.baseLayer.setVisibility(false);}
+this.baseLayer=newBaseLayer;this.viewRequestID++;if(!this.allOverlays||this.baseLayer.visibility){this.baseLayer.setVisibility(true);}
+if(center!=null){var newZoom=this.getZoomForResolution(newResolution||this.resolution,true);this.setCenter(center,newZoom,false,true);}
+this.events.triggerEvent("changebaselayer",{layer:this.baseLayer});}}},addControl:function(control,px){this.controls.push(control);this.addControlToMap(control,px);},addControls:function(controls,pixels){var pxs=(arguments.length===1)?[]:pixels;for(var i=0,len=controls.length;i<len;i++){var ctrl=controls[i];var px=(pxs[i])?pxs[i]:null;this.addControl(ctrl,px);}},addControlToMap:function(control,px){control.outsideViewport=(control.div!=null);if(this.displayProjection&&!control.displayProjection){control.displayProjection=this.displayProjection;}
+control.setMap(this);var div=control.draw(px);if(div){if(!control.outsideViewport){div.style.zIndex=this.Z_INDEX_BASE['Control']+
+this.controls.length;this.viewPortDiv.appendChild(div);}}
+if(control.autoActivate){control.activate();}},getControl:function(id){var returnControl=null;for(var i=0,len=this.controls.length;i<len;i++){var control=this.controls[i];if(control.id==id){returnControl=control;break;}}
+return returnControl;},removeControl:function(control){if((control)&&(control==this.getControl(control.id))){if(control.div&&(control.div.parentNode==this.viewPortDiv)){this.viewPortDiv.removeChild(control.div);}
+OpenLayers.Util.removeItem(this.controls,control);}},addPopup:function(popup,exclusive){if(exclusive){for(var i=this.popups.length-1;i>=0;--i){this.removePopup(this.popups[i]);}}
+popup.map=this;this.popups.push(popup);var popupDiv=popup.draw();if(popupDiv){popupDiv.style.zIndex=this.Z_INDEX_BASE['Popup']+
+this.popups.length;this.layerContainerDiv.appendChild(popupDiv);}},removePopup:function(popup){OpenLayers.Util.removeItem(this.popups,popup);if(popup.div){try{this.layerContainerDiv.removeChild(popup.div);}
+catch(e){}}
+popup.map=null;},getSize:function(){var size=null;if(this.size!=null){size=this.size.clone();}
+return size;},updateSize:function(){var newSize=this.getCurrentSize();if(newSize&&!isNaN(newSize.h)&&!isNaN(newSize.w)){this.events.clearMouseCache();var oldSize=this.getSize();if(oldSize==null){this.size=oldSize=newSize;}
+if(!newSize.equals(oldSize)){this.size=newSize;for(var i=0,len=this.layers.length;i<len;i++){this.layers[i].onMapResize();}
+var center=this.getCenter();if(this.baseLayer!=null&&center!=null){var zoom=this.getZoom();this.zoom=null;this.setCenter(center,zoom);}}}},getCurrentSize:function(){var size=new OpenLayers.Size(this.div.clientWidth,this.div.clientHeight);if(size.w==0&&size.h==0||isNaN(size.w)&&isNaN(size.h)){size.w=this.div.offsetWidth;size.h=this.div.offsetHeight;}
+if(size.w==0&&size.h==0||isNaN(size.w)&&isNaN(size.h)){size.w=parseInt(this.div.style.width);size.h=parseInt(this.div.style.height);}
+return size;},calculateBounds:function(center,resolution){var extent=null;if(center==null){center=this.getCenter();}
+if(resolution==null){resolution=this.getResolution();}
+if((center!=null)&&(resolution!=null)){var size=this.getSize();var w_deg=size.w*resolution;var h_deg=size.h*resolution;extent=new OpenLayers.Bounds(center.lon-w_deg/2,center.lat-h_deg/2,center.lon+w_deg/2,center.lat+h_deg/2);}
+return extent;},getCenter:function(){var center=null;if(this.center){center=this.center.clone();}
+return center;},getZoom:function(){return this.zoom;},pan:function(dx,dy,options){options=OpenLayers.Util.applyDefaults(options,{animate:true,dragging:false});var centerPx=this.getViewPortPxFromLonLat(this.getCenter());var newCenterPx=centerPx.add(dx,dy);if(!options.dragging||!newCenterPx.equals(centerPx)){var newCenterLonLat=this.getLonLatFromViewPortPx(newCenterPx);if(options.animate){this.panTo(newCenterLonLat);}else{this.setCenter(newCenterLonLat,null,options.dragging);}}},panTo:function(lonlat){if(this.panMethod&&this.getExtent().scale(this.panRatio).containsLonLat(lonlat)){if(!this.panTween){this.panTween=new OpenLayers.Tween(this.panMethod);}
+var center=this.getCenter();if(lonlat.lon==center.lon&&lonlat.lat==center.lat){return;}
+var from={lon:center.lon,lat:center.lat};var to={lon:lonlat.lon,lat:lonlat.lat};this.panTween.start(from,to,this.panDuration,{callbacks:{start:OpenLayers.Function.bind(function(lonlat){this.events.triggerEvent("movestart");},this),eachStep:OpenLayers.Function.bind(function(lonlat){lonlat=new OpenLayers.LonLat(lonlat.lon,lonlat.lat);this.moveTo(lonlat,this.zoom,{'dragging':true,'noEvent':true});},this),done:OpenLayers.Function.bind(function(lonlat){lonlat=new OpenLayers.LonLat(lonlat.lon,lonlat.lat);this.moveTo(lonlat,this.zoom,{'noEvent':true});this.events.triggerEvent("moveend");},this)}});}else{this.setCenter(lonlat);}},setCenter:function(lonlat,zoom,dragging,forceZoomChange){this.moveTo(lonlat,zoom,{'dragging':dragging,'forceZoomChange':forceZoomChange,'caller':'setCenter'});},moveTo:function(lonlat,zoom,options){if(!options){options={};}
+if(zoom!=null){zoom=parseFloat(zoom);if(!this.fractionalZoom){zoom=Math.round(zoom);}}
+var dragging=options.dragging;var forceZoomChange=options.forceZoomChange;var noEvent=options.noEvent;if(this.panTween&&options.caller=="setCenter"){this.panTween.stop();}
+if(!this.center&&!this.isValidLonLat(lonlat)){lonlat=this.maxExtent.getCenterLonLat();}
+if(this.restrictedExtent!=null){if(lonlat==null){lonlat=this.getCenter();}
+if(zoom==null){zoom=this.getZoom();}
+var resolution=this.getResolutionForZoom(zoom);var extent=this.calculateBounds(lonlat,resolution);if(!this.restrictedExtent.containsBounds(extent)){var maxCenter=this.restrictedExtent.getCenterLonLat();if(extent.getWidth()>this.restrictedExtent.getWidth()){lonlat=new OpenLayers.LonLat(maxCenter.lon,lonlat.lat);}else if(extent.left<this.restrictedExtent.left){lonlat=lonlat.add(this.restrictedExtent.left-
+extent.left,0);}else if(extent.right>this.restrictedExtent.right){lonlat=lonlat.add(this.restrictedExtent.right-
+extent.right,0);}
+if(extent.getHeight()>this.restrictedExtent.getHeight()){lonlat=new OpenLayers.LonLat(lonlat.lon,maxCenter.lat);}else if(extent.bottom<this.restrictedExtent.bottom){lonlat=lonlat.add(0,this.restrictedExtent.bottom-
+extent.bottom);}
+else if(extent.top>this.restrictedExtent.top){lonlat=lonlat.add(0,this.restrictedExtent.top-
+extent.top);}}}
+var zoomChanged=forceZoomChange||((this.isValidZoomLevel(zoom))&&(zoom!=this.getZoom()));var centerChanged=(this.isValidLonLat(lonlat))&&(!lonlat.equals(this.center));if(zoomChanged||centerChanged||!dragging){if(!this.dragging&&!noEvent){this.events.triggerEvent("movestart");}
+if(centerChanged){if((!zoomChanged)&&(this.center)){this.centerLayerContainer(lonlat);}
+this.center=lonlat.clone();}
+if((zoomChanged)||(this.layerContainerOrigin==null)){this.layerContainerOrigin=this.center.clone();this.layerContainerDiv.style.left="0px";this.layerContainerDiv.style.top="0px";}
+if(zoomChanged){this.zoom=zoom;this.resolution=this.getResolutionForZoom(zoom);this.viewRequestID++;}
+var bounds=this.getExtent();if(this.baseLayer.visibility){this.baseLayer.moveTo(bounds,zoomChanged,dragging);if(dragging){this.baseLayer.events.triggerEvent("move");}else{this.baseLayer.events.triggerEvent("moveend",{"zoomChanged":zoomChanged});}}
+bounds=this.baseLayer.getExtent();for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer!==this.baseLayer&&!layer.isBaseLayer){var inRange=layer.calculateInRange();if(layer.inRange!=inRange){layer.inRange=inRange;if(!inRange){layer.display(false);}
+this.events.triggerEvent("changelayer",{layer:layer,property:"visibility"});}
+if(inRange&&layer.visibility){layer.moveTo(bounds,zoomChanged,dragging);if(dragging){layer.events.triggerEvent("move");}else{layer.events.triggerEvent("moveend",{"zoomChanged":zoomChanged});}}}}
+if(zoomChanged){for(var i=0,len=this.popups.length;i<len;i++){this.popups[i].updatePosition();}}
+this.events.triggerEvent("move");if(zoomChanged){this.events.triggerEvent("zoomend");}}
+if(!dragging&&!noEvent){this.events.triggerEvent("moveend");}
+this.dragging=!!dragging;},centerLayerContainer:function(lonlat){var originPx=this.getViewPortPxFromLonLat(this.layerContainerOrigin);var newPx=this.getViewPortPxFromLonLat(lonlat);if((originPx!=null)&&(newPx!=null)){this.layerContainerDiv.style.left=Math.round(originPx.x-newPx.x)+"px";this.layerContainerDiv.style.top=Math.round(originPx.y-newPx.y)+"px";}},isValidZoomLevel:function(zoomLevel){return((zoomLevel!=null)&&(zoomLevel>=0)&&(zoomLevel<this.getNumZoomLevels()));},isValidLonLat:function(lonlat){var valid=false;if(lonlat!=null){var maxExtent=this.getMaxExtent();valid=maxExtent.containsLonLat(lonlat);}
+return valid;},getProjection:function(){var projection=this.getProjectionObject();return projection?projection.getCode():null;},getProjectionObject:function(){var projection=null;if(this.baseLayer!=null){projection=this.baseLayer.projection;}
+return projection;},getMaxResolution:function(){var maxResolution=null;if(this.baseLayer!=null){maxResolution=this.baseLayer.maxResolution;}
+return maxResolution;},getMaxExtent:function(options){var maxExtent=null;if(options&&options.restricted&&this.restrictedExtent){maxExtent=this.restrictedExtent;}else if(this.baseLayer!=null){maxExtent=this.baseLayer.maxExtent;}
+return maxExtent;},getNumZoomLevels:function(){var numZoomLevels=null;if(this.baseLayer!=null){numZoomLevels=this.baseLayer.numZoomLevels;}
+return numZoomLevels;},getExtent:function(){var extent=null;if(this.baseLayer!=null){extent=this.baseLayer.getExtent();}
+return extent;},getResolution:function(){var resolution=null;if(this.baseLayer!=null){resolution=this.baseLayer.getResolution();}else if(this.allOverlays===true&&this.layers.length>0){resolution=this.layers[0].getResolution();}
+return resolution;},getUnits:function(){var units=null;if(this.baseLayer!=null){units=this.baseLayer.units;}
+return units;},getScale:function(){var scale=null;if(this.baseLayer!=null){var res=this.getResolution();var units=this.baseLayer.units;scale=OpenLayers.Util.getScaleFromResolution(res,units);}
+return scale;},getZoomForExtent:function(bounds,closest){var zoom=null;if(this.baseLayer!=null){zoom=this.baseLayer.getZoomForExtent(bounds,closest);}
+return zoom;},getResolutionForZoom:function(zoom){var resolution=null;if(this.baseLayer){resolution=this.baseLayer.getResolutionForZoom(zoom);}
+return resolution;},getZoomForResolution:function(resolution,closest){var zoom=null;if(this.baseLayer!=null){zoom=this.baseLayer.getZoomForResolution(resolution,closest);}
+return zoom;},zoomTo:function(zoom){if(this.isValidZoomLevel(zoom)){this.setCenter(null,zoom);}},zoomIn:function(){this.zoomTo(this.getZoom()+1);},zoomOut:function(){this.zoomTo(this.getZoom()-1);},zoomToExtent:function(bounds,closest){var center=bounds.getCenterLonLat();if(this.baseLayer.wrapDateLine){var maxExtent=this.getMaxExtent();bounds=bounds.clone();while(bounds.right<bounds.left){bounds.right+=maxExtent.getWidth();}
+center=bounds.getCenterLonLat().wrapDateLine(maxExtent);}
+this.setCenter(center,this.getZoomForExtent(bounds,closest));},zoomToMaxExtent:function(options){var restricted=(options)?options.restricted:true;var maxExtent=this.getMaxExtent({'restricted':restricted});this.zoomToExtent(maxExtent);},zoomToScale:function(scale,closest){var res=OpenLayers.Util.getResolutionFromScale(scale,this.baseLayer.units);var size=this.getSize();var w_deg=size.w*res;var h_deg=size.h*res;var center=this.getCenter();var extent=new OpenLayers.Bounds(center.lon-w_deg/2,center.lat-h_deg/2,center.lon+w_deg/2,center.lat+h_deg/2);this.zoomToExtent(extent,closest);},getLonLatFromViewPortPx:function(viewPortPx){var lonlat=null;if(this.baseLayer!=null){lonlat=this.baseLayer.getLonLatFromViewPortPx(viewPortPx);}
+return lonlat;},getViewPortPxFromLonLat:function(lonlat){var px=null;if(this.baseLayer!=null){px=this.baseLayer.getViewPortPxFromLonLat(lonlat);}
+return px;},getLonLatFromPixel:function(px){return this.getLonLatFromViewPortPx(px);},getPixelFromLonLat:function(lonlat){var px=this.getViewPortPxFromLonLat(lonlat);px.x=Math.round(px.x);px.y=Math.round(px.y);return px;},getGeodesicPixelSize:function(px){var lonlat=px?this.getLonLatFromPixel(px):(this.getCenter()||new OpenLayers.LonLat(0,0));var res=this.getResolution();var left=lonlat.add(-res/2,0);var right=lonlat.add(res/2,0);var bottom=lonlat.add(0,-res/2);var top=lonlat.add(0,res/2);var dest=new OpenLayers.Projection("EPSG:4326");var source=this.getProjectionObject()||dest;if(!source.equals(dest)){left.transform(source,dest);right.transform(source,dest);bottom.transform(source,dest);top.transform(source,dest);}
+return new OpenLayers.Size(OpenLayers.Util.distVincenty(left,right),OpenLayers.Util.distVincenty(bottom,top));},getViewPortPxFromLayerPx:function(layerPx){var viewPortPx=null;if(layerPx!=null){var dX=parseInt(this.layerContainerDiv.style.left);var dY=parseInt(this.layerContainerDiv.style.top);viewPortPx=layerPx.add(dX,dY);}
+return viewPortPx;},getLayerPxFromViewPortPx:function(viewPortPx){var layerPx=null;if(viewPortPx!=null){var dX=-parseInt(this.layerContainerDiv.style.left);var dY=-parseInt(this.layerContainerDiv.style.top);layerPx=viewPortPx.add(dX,dY);if(isNaN(layerPx.x)||isNaN(layerPx.y)){layerPx=null;}}
+return layerPx;},getLonLatFromLayerPx:function(px){px=this.getViewPortPxFromLayerPx(px);return this.getLonLatFromViewPortPx(px);},getLayerPxFromLonLat:function(lonlat){var px=this.getPixelFromLonLat(lonlat);return this.getLayerPxFromViewPortPx(px);},CLASS_NAME:"OpenLayers.Map"});OpenLayers.Map.TILE_WIDTH=256;OpenLayers.Map.TILE_HEIGHT=256;OpenLayers.Marker=OpenLayers.Class({icon:null,lonlat:null,events:null,map:null,initialize:function(lonlat,icon){this.lonlat=lonlat;var newIcon=(icon)?icon:OpenLayers.Marker.defaultIcon();if(this.icon==null){this.icon=newIcon;}else{this.icon.url=newIcon.url;this.icon.size=newIcon.size;this.icon.offset=newIcon.offset;this.icon.calculateOffset=newIcon.calculateOffset;}
+this.events=new OpenLayers.Events(this,this.icon.imageDiv,null);},destroy:function(){this.erase();this.map=null;this.events.destroy();this.events=null;if(this.icon!=null){this.icon.destroy();this.icon=null;}},draw:function(px){return this.icon.draw(px);},erase:function(){if(this.icon!=null){this.icon.erase();}},moveTo:function(px){if((px!=null)&&(this.icon!=null)){this.icon.moveTo(px);}
+this.lonlat=this.map.getLonLatFromLayerPx(px);},isDrawn:function(){var isDrawn=(this.icon&&this.icon.isDrawn());return isDrawn;},onScreen:function(){var onScreen=false;if(this.map){var screenBounds=this.map.getExtent();onScreen=screenBounds.containsLonLat(this.lonlat);}
+return onScreen;},inflate:function(inflate){if(this.icon){var newSize=new OpenLayers.Size(this.icon.size.w*inflate,this.icon.size.h*inflate);this.icon.setSize(newSize);}},setOpacity:function(opacity){this.icon.setOpacity(opacity);},setUrl:function(url){this.icon.setUrl(url);},display:function(display){this.icon.display(display);},CLASS_NAME:"OpenLayers.Marker"});OpenLayers.Marker.defaultIcon=function(){var url=OpenLayers.Util.getImagesLocation()+"marker.png";var size=new OpenLayers.Size(21,25);var calculateOffset=function(size){return new OpenLayers.Pixel(-(size.w/2),-size.h);};return new OpenLayers.Icon(url,size,null,calculateOffset);};OpenLayers.Popup.FramedCloud=OpenLayers.Class(OpenLayers.Popup.Framed,{contentDisplayClass:"olFramedCloudPopupContent",autoSize:true,panMapIfOutOfView:true,imageSize:new OpenLayers.Size(1276,736),isAlphaImage:false,fixedRelativePosition:false,positionBlocks:{"tl":{'offset':new OpenLayers.Pixel(44,0),'padding':new OpenLayers.Bounds(8,40,8,9),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,51,22,0),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,50,0,0),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',19),anchor:new OpenLayers.Bounds(0,32,22,null),position:new OpenLayers.Pixel(0,-631)},{size:new OpenLayers.Size(22,18),anchor:new OpenLayers.Bounds(null,32,0,null),position:new OpenLayers.Pixel(-1238,-632)},{size:new OpenLayers.Size(81,35),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(0,-688)}]},"tr":{'offset':new OpenLayers.Pixel(-45,0),'padding':new OpenLayers.Bounds(8,40,8,9),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,51,22,0),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,50,0,0),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',19),anchor:new OpenLayers.Bounds(0,32,22,null),position:new OpenLayers.Pixel(0,-631)},{size:new OpenLayers.Size(22,19),anchor:new OpenLayers.Bounds(null,32,0,null),position:new OpenLayers.Pixel(-1238,-631)},{size:new OpenLayers.Size(81,35),anchor:new OpenLayers.Bounds(0,0,null,null),position:new OpenLayers.Pixel(-215,-687)}]},"bl":{'offset':new OpenLayers.Pixel(45,0),'padding':new OpenLayers.Bounds(8,9,8,40),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,21,22,32),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,21,0,32),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',21),anchor:new OpenLayers.Bounds(0,0,22,null),position:new OpenLayers.Pixel(0,-629)},{size:new OpenLayers.Size(22,21),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(-1238,-629)},{size:new OpenLayers.Size(81,33),anchor:new OpenLayers.Bounds(null,null,0,0),position:new OpenLayers.Pixel(-101,-674)}]},"br":{'offset':new OpenLayers.Pixel(-44,0),'padding':new OpenLayers.Bounds(8,9,8,40),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,21,22,32),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,21,0,32),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',21),anchor:new OpenLayers.Bounds(0,0,22,null),position:new OpenLayers.Pixel(0,-629)},{size:new OpenLayers.Size(22,21),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(-1238,-629)},{size:new OpenLayers.Size(81,33),anchor:new OpenLayers.Bounds(0,null,null,0),position:new OpenLayers.Pixel(-311,-674)}]}},minSize:new OpenLayers.Size(105,10),maxSize:new OpenLayers.Size(1200,660),initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){this.imageSrc=OpenLayers.Util.getImagesLocation()+'cloud-popup-relative.png';OpenLayers.Popup.Framed.prototype.initialize.apply(this,arguments);this.contentDiv.className=this.contentDisplayClass;},destroy:function(){OpenLayers.Popup.Framed.prototype.destroy.apply(this,arguments);},CLASS_NAME:"OpenLayers.Popup.FramedCloud"});OpenLayers.Request={DEFAULT_CONFIG:{method:"GET",url:window.location.href,async:true,user:undefined,password:undefined,params:null,proxy:OpenLayers.ProxyHost,headers:{},data:null,callback:function(){},success:null,failure:null,scope:null},events:new OpenLayers.Events(this,null,["complete","success","failure"]),issue:function(config){var defaultConfig=OpenLayers.Util.extend(this.DEFAULT_CONFIG,{proxy:OpenLayers.ProxyHost});config=OpenLayers.Util.applyDefaults(config,defaultConfig);var request=new OpenLayers.Request.XMLHttpRequest();var url=config.url;if(config.params){var paramString=OpenLayers.Util.getParameterString(config.params);if(paramString.length>0){var separator=(url.indexOf('?')>-1)?'&':'?';url+=separator+paramString;}}
+if(config.proxy&&(url.indexOf("http")==0)){if(typeof config.proxy=="function"){url=config.proxy(url);}else{url=config.proxy+encodeURIComponent(url);}}
+request.open(config.method,url,config.async,config.user,config.password);for(var header in config.headers){request.setRequestHeader(header,config.headers[header]);}
+var events=this.events;var self=this;request.onreadystatechange=function(){if(request.readyState==OpenLayers.Request.XMLHttpRequest.DONE){var proceed=events.triggerEvent("complete",{request:request,config:config,requestUrl:url});if(proceed!==false){self.runCallbacks({request:request,config:config,requestUrl:url});}}};if(config.async===false){request.send(config.data);}else{window.setTimeout(function(){if(request._aborted!==true){request.send(config.data);}},0);}
+return request;},runCallbacks:function(options){var request=options.request;var config=options.config;var complete=(config.scope)?OpenLayers.Function.bind(config.callback,config.scope):config.callback;var success;if(config.success){success=(config.scope)?OpenLayers.Function.bind(config.success,config.scope):config.success;}
+var failure;if(config.failure){failure=(config.scope)?OpenLayers.Function.bind(config.failure,config.scope):config.failure;}
+complete(request);if(!request.status||(request.status>=200&&request.status<300)){this.events.triggerEvent("success",options);if(success){success(request);}}
+if(request.status&&(request.status<200||request.status>=300)){this.events.triggerEvent("failure",options);if(failure){failure(request);}}},GET:function(config){config=OpenLayers.Util.extend(config,{method:"GET"});return OpenLayers.Request.issue(config);},POST:function(config){config=OpenLayers.Util.extend(config,{method:"POST"});config.headers=config.headers?config.headers:{};if(!("CONTENT-TYPE"in OpenLayers.Util.upperCaseObject(config.headers))){config.headers["Content-Type"]="application/xml";}
+return OpenLayers.Request.issue(config);},PUT:function(config){config=OpenLayers.Util.extend(config,{method:"PUT"});config.headers=config.headers?config.headers:{};if(!("CONTENT-TYPE"in OpenLayers.Util.upperCaseObject(config.headers))){config.headers["Content-Type"]="application/xml";}
+return OpenLayers.Request.issue(config);},DELETE:function(config){config=OpenLayers.Util.extend(config,{method:"DELETE"});return OpenLayers.Request.issue(config);},HEAD:function(config){config=OpenLayers.Util.extend(config,{method:"HEAD"});return OpenLayers.Request.issue(config);},OPTIONS:function(config){config=OpenLayers.Util.extend(config,{method:"OPTIONS"});return OpenLayers.Request.issue(config);}};OpenLayers.Tile.Image=OpenLayers.Class(OpenLayers.Tile,{url:null,imgDiv:null,frame:null,layerAlphaHack:null,isBackBuffer:false,lastRatio:1,isFirstDraw:true,backBufferTile:null,initialize:function(layer,position,bounds,url,size){OpenLayers.Tile.prototype.initialize.apply(this,arguments);this.url=url;this.frame=document.createElement('div');this.frame.style.overflow='hidden';this.frame.style.position='absolute';this.layerAlphaHack=this.layer.alpha&&OpenLayers.Util.alphaHack();},destroy:function(){if(this.imgDiv!=null){if(this.layerAlphaHack){OpenLayers.Event.stopObservingElement(this.imgDiv.childNodes[0]);}
+OpenLayers.Event.stopObservingElement(this.imgDiv);if(this.imgDiv.parentNode==this.frame){this.frame.removeChild(this.imgDiv);this.imgDiv.map=null;}
+this.imgDiv.urls=null;this.imgDiv.src=OpenLayers.Util.getImagesLocation()+"blank.gif";}
+this.imgDiv=null;if((this.frame!=null)&&(this.frame.parentNode==this.layer.div)){this.layer.div.removeChild(this.frame);}
+this.frame=null;if(this.backBufferTile){this.backBufferTile.destroy();this.backBufferTile=null;}
+this.layer.events.unregister("loadend",this,this.resetBackBuffer);OpenLayers.Tile.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile.Image(this.layer,this.position,this.bounds,this.url,this.size);}
+obj=OpenLayers.Tile.prototype.clone.apply(this,[obj]);obj.imgDiv=null;return obj;},draw:function(){if(this.layer!=this.layer.map.baseLayer&&this.layer.reproject){this.bounds=this.getBoundsFromBaseLayer(this.position);}
+var drawTile=OpenLayers.Tile.prototype.draw.apply(this,arguments);if((OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS,this.layer.transitionEffect)!=-1)||this.layer.singleTile){if(drawTile){if(!this.backBufferTile){this.backBufferTile=this.clone();this.backBufferTile.hide();this.backBufferTile.isBackBuffer=true;this.events.register('loadend',this,this.resetBackBuffer);this.layer.events.register("loadend",this,this.resetBackBuffer);}
+this.startTransition();}else{if(this.backBufferTile){this.backBufferTile.clear();}}}else{if(drawTile&&this.isFirstDraw){this.events.register('loadend',this,this.showTile);this.isFirstDraw=false;}}
+if(!drawTile){return false;}
+if(this.isLoading){this.events.triggerEvent("reload");}else{this.isLoading=true;this.events.triggerEvent("loadstart");}
+return this.renderTile();},resetBackBuffer:function(){this.showTile();if(this.backBufferTile&&(this.isFirstDraw||!this.layer.numLoadingTiles)){this.isFirstDraw=false;var maxExtent=this.layer.maxExtent;var withinMaxExtent=(maxExtent&&this.bounds.intersectsBounds(maxExtent,false));if(withinMaxExtent){this.backBufferTile.position=this.position;this.backBufferTile.bounds=this.bounds;this.backBufferTile.size=this.size;this.backBufferTile.imageSize=this.layer.getImageSize(this.bounds)||this.size;this.backBufferTile.imageOffset=this.layer.imageOffset;this.backBufferTile.resolution=this.layer.getResolution();this.backBufferTile.renderTile();}
+this.backBufferTile.hide();}},renderTile:function(){if(this.imgDiv==null){this.initImgDiv();}
+this.imgDiv.viewRequestID=this.layer.map.viewRequestID;if(this.layer.async){this.layer.getURLasync(this.bounds,this,"url",this.positionImage);}else{if(this.layer.url instanceof Array){this.imgDiv.urls=this.layer.url.slice();}
+this.url=this.layer.getURL(this.bounds);this.positionImage();}
+return true;},positionImage:function(){if(this.layer===null){return;}
+OpenLayers.Util.modifyDOMElement(this.frame,null,this.position,this.size);var imageSize=this.layer.getImageSize(this.bounds);if(this.layerAlphaHack){OpenLayers.Util.modifyAlphaImageDiv(this.imgDiv,null,null,imageSize,this.url);}else{OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,imageSize);this.imgDiv.src=this.url;}},clear:function(){if(this.imgDiv){this.hide();if(OpenLayers.Tile.Image.useBlankTile){this.imgDiv.src=OpenLayers.Util.getImagesLocation()+"blank.gif";}}},initImgDiv:function(){var offset=this.layer.imageOffset;var size=this.layer.getImageSize(this.bounds);if(this.layerAlphaHack){this.imgDiv=OpenLayers.Util.createAlphaImageDiv(null,offset,size,null,"relative",null,null,null,true);}else{this.imgDiv=OpenLayers.Util.createImage(null,offset,size,null,"relative",null,null,true);}
+this.imgDiv.className='olTileImage';this.frame.style.zIndex=this.isBackBuffer?0:1;this.frame.appendChild(this.imgDiv);this.layer.div.appendChild(this.frame);if(this.layer.opacity!=null){OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,null,null,null,null,this.layer.opacity);}
+this.imgDiv.map=this.layer.map;var onload=function(){if(this.isLoading){this.isLoading=false;this.events.triggerEvent("loadend");}};if(this.layerAlphaHack){OpenLayers.Event.observe(this.imgDiv.childNodes[0],'load',OpenLayers.Function.bind(onload,this));}else{OpenLayers.Event.observe(this.imgDiv,'load',OpenLayers.Function.bind(onload,this));}
+var onerror=function(){if(this.imgDiv._attempts>OpenLayers.IMAGE_RELOAD_ATTEMPTS){onload.call(this);}};OpenLayers.Event.observe(this.imgDiv,"error",OpenLayers.Function.bind(onerror,this));},checkImgURL:function(){if(this.layer){var loaded=this.layerAlphaHack?this.imgDiv.firstChild.src:this.imgDiv.src;if(!OpenLayers.Util.isEquivalentUrl(loaded,this.url)){this.hide();}}},startTransition:function(){if(!this.backBufferTile||!this.backBufferTile.imgDiv){return;}
+var ratio=1;if(this.backBufferTile.resolution){ratio=this.backBufferTile.resolution/this.layer.getResolution();}
+if(ratio!=this.lastRatio){if(this.layer.transitionEffect=='resize'){var upperLeft=new OpenLayers.LonLat(this.backBufferTile.bounds.left,this.backBufferTile.bounds.top);var size=new OpenLayers.Size(this.backBufferTile.size.w*ratio,this.backBufferTile.size.h*ratio);var px=this.layer.map.getLayerPxFromLonLat(upperLeft);OpenLayers.Util.modifyDOMElement(this.backBufferTile.frame,null,px,size);var imageSize=this.backBufferTile.imageSize;imageSize=new OpenLayers.Size(imageSize.w*ratio,imageSize.h*ratio);var imageOffset=this.backBufferTile.imageOffset;if(imageOffset){imageOffset=new OpenLayers.Pixel(imageOffset.x*ratio,imageOffset.y*ratio);}
+OpenLayers.Util.modifyDOMElement(this.backBufferTile.imgDiv,null,imageOffset,imageSize);this.backBufferTile.show();}}else{if(this.layer.singleTile){this.backBufferTile.show();}else{this.backBufferTile.hide();}}
+this.lastRatio=ratio;},show:function(){this.frame.style.display='';if(OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS,this.layer.transitionEffect)!=-1){if(navigator.userAgent.toLowerCase().indexOf("gecko")!=-1){this.frame.scrollLeft=this.frame.scrollLeft;}}},hide:function(){this.frame.style.display='none';},CLASS_NAME:"OpenLayers.Tile.Image"});OpenLayers.Tile.Image.useBlankTile=(OpenLayers.Util.getBrowserName()=="safari"||OpenLayers.Util.getBrowserName()=="opera");OpenLayers.Control.OverviewMap=OpenLayers.Class(OpenLayers.Control,{element:null,ovmap:null,size:new OpenLayers.Size(180,90),layers:null,minRectSize:15,minRectDisplayClass:"RectReplacement",minRatio:8,maxRatio:32,mapOptions:null,autoPan:false,handlers:null,resolutionFactor:1,maximized:false,initialize:function(options){this.layers=[];this.handlers={};OpenLayers.Control.prototype.initialize.apply(this,[options]);},destroy:function(){if(!this.mapDiv){return;}
+if(this.handlers.click){this.handlers.click.destroy();}
+if(this.handlers.drag){this.handlers.drag.destroy();}
+this.mapDiv.removeChild(this.extentRectangle);this.extentRectangle=null;if(this.rectEvents){this.rectEvents.destroy();this.rectEvents=null;}
+if(this.ovmap){this.ovmap.destroy();this.ovmap=null;}
+this.element.removeChild(this.mapDiv);this.mapDiv=null;this.div.removeChild(this.element);this.element=null;if(this.maximizeDiv){OpenLayers.Event.stopObservingElement(this.maximizeDiv);this.div.removeChild(this.maximizeDiv);this.maximizeDiv=null;}
+if(this.minimizeDiv){OpenLayers.Event.stopObservingElement(this.minimizeDiv);this.div.removeChild(this.minimizeDiv);this.minimizeDiv=null;}
+this.map.events.un({"moveend":this.update,"changebaselayer":this.baseLayerDraw,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!(this.layers.length>0)){if(this.map.baseLayer){var layer=this.map.baseLayer.clone();this.layers=[layer];}else{this.map.events.register("changebaselayer",this,this.baseLayerDraw);return this.div;}}
+this.element=document.createElement('div');this.element.className=this.displayClass+'Element';this.element.style.display='none';this.mapDiv=document.createElement('div');this.mapDiv.style.width=this.size.w+'px';this.mapDiv.style.height=this.size.h+'px';this.mapDiv.style.position='relative';this.mapDiv.style.overflow='hidden';this.mapDiv.id=OpenLayers.Util.createUniqueID('overviewMap');this.extentRectangle=document.createElement('div');this.extentRectangle.style.position='absolute';this.extentRectangle.style.zIndex=1000;this.extentRectangle.className=this.displayClass+'ExtentRectangle';this.mapDiv.appendChild(this.extentRectangle);this.element.appendChild(this.mapDiv);this.div.appendChild(this.element);if(!this.outsideViewport){this.div.className+=" "+this.displayClass+'Container';var imgLocation=OpenLayers.Util.getImagesLocation();var img=imgLocation+'layer-switcher-maximize.png';this.maximizeDiv=OpenLayers.Util.createAlphaImageDiv(this.displayClass+'MaximizeButton',null,new OpenLayers.Size(18,18),img,'absolute');this.maximizeDiv.style.display='none';this.maximizeDiv.className=this.displayClass+'MaximizeButton';OpenLayers.Event.observe(this.maximizeDiv,'click',OpenLayers.Function.bindAsEventListener(this.maximizeControl,this));this.div.appendChild(this.maximizeDiv);var img=imgLocation+'layer-switcher-minimize.png';this.minimizeDiv=OpenLayers.Util.createAlphaImageDiv('OpenLayers_Control_minimizeDiv',null,new OpenLayers.Size(18,18),img,'absolute');this.minimizeDiv.style.display='none';this.minimizeDiv.className=this.displayClass+'MinimizeButton';OpenLayers.Event.observe(this.minimizeDiv,'click',OpenLayers.Function.bindAsEventListener(this.minimizeControl,this));this.div.appendChild(this.minimizeDiv);var eventsToStop=['dblclick','mousedown'];for(var i=0,len=eventsToStop.length;i<len;i++){OpenLayers.Event.observe(this.maximizeDiv,eventsToStop[i],OpenLayers.Event.stop);OpenLayers.Event.observe(this.minimizeDiv,eventsToStop[i],OpenLayers.Event.stop);}
+this.minimizeControl();}else{this.element.style.display='';}
+if(this.map.getExtent()){this.update();}
+this.map.events.register('moveend',this,this.update);if(this.maximized){this.maximizeControl();}
+return this.div;},baseLayerDraw:function(){this.draw();this.map.events.unregister("changebaselayer",this,this.baseLayerDraw);},rectDrag:function(px){var deltaX=this.handlers.drag.last.x-px.x;var deltaY=this.handlers.drag.last.y-px.y;if(deltaX!=0||deltaY!=0){var rectTop=this.rectPxBounds.top;var rectLeft=this.rectPxBounds.left;var rectHeight=Math.abs(this.rectPxBounds.getHeight());var rectWidth=this.rectPxBounds.getWidth();var newTop=Math.max(0,(rectTop-deltaY));newTop=Math.min(newTop,this.ovmap.size.h-this.hComp-rectHeight);var newLeft=Math.max(0,(rectLeft-deltaX));newLeft=Math.min(newLeft,this.ovmap.size.w-this.wComp-rectWidth);this.setRectPxBounds(new OpenLayers.Bounds(newLeft,newTop+rectHeight,newLeft+rectWidth,newTop));}},mapDivClick:function(evt){var pxCenter=this.rectPxBounds.getCenterPixel();var deltaX=evt.xy.x-pxCenter.x;var deltaY=evt.xy.y-pxCenter.y;var top=this.rectPxBounds.top;var left=this.rectPxBounds.left;var height=Math.abs(this.rectPxBounds.getHeight());var width=this.rectPxBounds.getWidth();var newTop=Math.max(0,(top+deltaY));newTop=Math.min(newTop,this.ovmap.size.h-height);var newLeft=Math.max(0,(left+deltaX));newLeft=Math.min(newLeft,this.ovmap.size.w-width);this.setRectPxBounds(new OpenLayers.Bounds(newLeft,newTop+height,newLeft+width,newTop));this.updateMapToRect();},maximizeControl:function(e){this.element.style.display='';this.showToggle(false);if(e!=null){OpenLayers.Event.stop(e);}},minimizeControl:function(e){this.element.style.display='none';this.showToggle(true);if(e!=null){OpenLayers.Event.stop(e);}},showToggle:function(minimize){this.maximizeDiv.style.display=minimize?'':'none';this.minimizeDiv.style.display=minimize?'none':'';},update:function(){if(this.ovmap==null){this.createMap();}
+if(this.autoPan||!this.isSuitableOverview()){this.updateOverview();}
+this.updateRectToMap();},isSuitableOverview:function(){var mapExtent=this.map.getExtent();var maxExtent=this.map.maxExtent;var testExtent=new OpenLayers.Bounds(Math.max(mapExtent.left,maxExtent.left),Math.max(mapExtent.bottom,maxExtent.bottom),Math.min(mapExtent.right,maxExtent.right),Math.min(mapExtent.top,maxExtent.top));if(this.ovmap.getProjection()!=this.map.getProjection()){testExtent=testExtent.transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject());}
+var resRatio=this.ovmap.getResolution()/this.map.getResolution();return((resRatio>this.minRatio)&&(resRatio<=this.maxRatio)&&(this.ovmap.getExtent().containsBounds(testExtent)));},updateOverview:function(){var mapRes=this.map.getResolution();var targetRes=this.ovmap.getResolution();var resRatio=targetRes/mapRes;if(resRatio>this.maxRatio){targetRes=this.minRatio*mapRes;}else if(resRatio<=this.minRatio){targetRes=this.maxRatio*mapRes;}
+var center;if(this.ovmap.getProjection()!=this.map.getProjection()){center=this.map.center.clone();center.transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject());}else{center=this.map.center;}
+this.ovmap.setCenter(center,this.ovmap.getZoomForResolution(targetRes*this.resolutionFactor));this.updateRectToMap();},createMap:function(){var options=OpenLayers.Util.extend({controls:[],maxResolution:'auto',fallThrough:false},this.mapOptions);this.ovmap=new OpenLayers.Map(this.mapDiv,options);OpenLayers.Event.stopObserving(window,'unload',this.ovmap.unloadDestroy);this.ovmap.addLayers(this.layers);this.ovmap.zoomToMaxExtent();this.wComp=parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-left-width'))+
+parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-right-width'));this.wComp=(this.wComp)?this.wComp:2;this.hComp=parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-top-width'))+
+parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-bottom-width'));this.hComp=(this.hComp)?this.hComp:2;this.handlers.drag=new OpenLayers.Handler.Drag(this,{move:this.rectDrag,done:this.updateMapToRect},{map:this.ovmap});this.handlers.click=new OpenLayers.Handler.Click(this,{"click":this.mapDivClick},{"single":true,"double":false,"stopSingle":true,"stopDouble":true,"pixelTolerance":1,map:this.ovmap});this.handlers.click.activate();this.rectEvents=new OpenLayers.Events(this,this.extentRectangle,null,true);this.rectEvents.register("mouseover",this,function(e){if(!this.handlers.drag.active&&!this.map.dragging){this.handlers.drag.activate();}});this.rectEvents.register("mouseout",this,function(e){if(!this.handlers.drag.dragging){this.handlers.drag.deactivate();}});if(this.ovmap.getProjection()!=this.map.getProjection()){var sourceUnits=this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units;var targetUnits=this.ovmap.getProjectionObject().getUnits()||this.ovmap.units||this.ovmap.baseLayer.units;this.resolutionFactor=sourceUnits&&targetUnits?OpenLayers.INCHES_PER_UNIT[sourceUnits]/OpenLayers.INCHES_PER_UNIT[targetUnits]:1;}},updateRectToMap:function(){var bounds;if(this.ovmap.getProjection()!=this.map.getProjection()){bounds=this.map.getExtent().transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject());}else{bounds=this.map.getExtent();}
+var pxBounds=this.getRectBoundsFromMapBounds(bounds);if(pxBounds){this.setRectPxBounds(pxBounds);}},updateMapToRect:function(){var lonLatBounds=this.getMapBoundsFromRectBounds(this.rectPxBounds);if(this.ovmap.getProjection()!=this.map.getProjection()){lonLatBounds=lonLatBounds.transform(this.ovmap.getProjectionObject(),this.map.getProjectionObject());}
+this.map.panTo(lonLatBounds.getCenterLonLat());},setRectPxBounds:function(pxBounds){var top=Math.max(pxBounds.top,0);var left=Math.max(pxBounds.left,0);var bottom=Math.min(pxBounds.top+Math.abs(pxBounds.getHeight()),this.ovmap.size.h-this.hComp);var right=Math.min(pxBounds.left+pxBounds.getWidth(),this.ovmap.size.w-this.wComp);var width=Math.max(right-left,0);var height=Math.max(bottom-top,0);if(width<this.minRectSize||height<this.minRectSize){this.extentRectangle.className=this.displayClass+
+this.minRectDisplayClass;var rLeft=left+(width/2)-(this.minRectSize/2);var rTop=top+(height/2)-(this.minRectSize/2);this.extentRectangle.style.top=Math.round(rTop)+'px';this.extentRectangle.style.left=Math.round(rLeft)+'px';this.extentRectangle.style.height=this.minRectSize+'px';this.extentRectangle.style.width=this.minRectSize+'px';}else{this.extentRectangle.className=this.displayClass+'ExtentRectangle';this.extentRectangle.style.top=Math.round(top)+'px';this.extentRectangle.style.left=Math.round(left)+'px';this.extentRectangle.style.height=Math.round(height)+'px';this.extentRectangle.style.width=Math.round(width)+'px';}
+this.rectPxBounds=new OpenLayers.Bounds(Math.round(left),Math.round(bottom),Math.round(right),Math.round(top));},getRectBoundsFromMapBounds:function(lonLatBounds){var leftBottomLonLat=new OpenLayers.LonLat(lonLatBounds.left,lonLatBounds.bottom);var rightTopLonLat=new OpenLayers.LonLat(lonLatBounds.right,lonLatBounds.top);var leftBottomPx=this.getOverviewPxFromLonLat(leftBottomLonLat);var rightTopPx=this.getOverviewPxFromLonLat(rightTopLonLat);var bounds=null;if(leftBottomPx&&rightTopPx){bounds=new OpenLayers.Bounds(leftBottomPx.x,leftBottomPx.y,rightTopPx.x,rightTopPx.y);}
+return bounds;},getMapBoundsFromRectBounds:function(pxBounds){var leftBottomPx=new OpenLayers.Pixel(pxBounds.left,pxBounds.bottom);var rightTopPx=new OpenLayers.Pixel(pxBounds.right,pxBounds.top);var leftBottomLonLat=this.getLonLatFromOverviewPx(leftBottomPx);var rightTopLonLat=this.getLonLatFromOverviewPx(rightTopPx);return new OpenLayers.Bounds(leftBottomLonLat.lon,leftBottomLonLat.lat,rightTopLonLat.lon,rightTopLonLat.lat);},getLonLatFromOverviewPx:function(overviewMapPx){var size=this.ovmap.size;var res=this.ovmap.getResolution();var center=this.ovmap.getExtent().getCenterLonLat();var delta_x=overviewMapPx.x-(size.w/2);var delta_y=overviewMapPx.y-(size.h/2);return new OpenLayers.LonLat(center.lon+delta_x*res,center.lat-delta_y*res);},getOverviewPxFromLonLat:function(lonlat){var res=this.ovmap.getResolution();var extent=this.ovmap.getExtent();var px=null;if(extent){px=new OpenLayers.Pixel(Math.round(1/res*(lonlat.lon-extent.left)),Math.round(1/res*(extent.top-lonlat.lat)));}
+return px;},CLASS_NAME:'OpenLayers.Control.OverviewMap'});OpenLayers.Feature=OpenLayers.Class({layer:null,id:null,lonlat:null,data:null,marker:null,popupClass:OpenLayers.Popup.AnchoredBubble,popup:null,initialize:function(layer,lonlat,data){this.layer=layer;this.lonlat=lonlat;this.data=(data!=null)?data:{};this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){if((this.layer!=null)&&(this.layer.map!=null)){if(this.popup!=null){this.layer.map.removePopup(this.popup);}}
+if(this.layer!=null&&this.marker!=null){this.layer.removeMarker(this.marker);}
+this.layer=null;this.id=null;this.lonlat=null;this.data=null;if(this.marker!=null){this.destroyMarker(this.marker);this.marker=null;}
+if(this.popup!=null){this.destroyPopup(this.popup);this.popup=null;}},onScreen:function(){var onScreen=false;if((this.layer!=null)&&(this.layer.map!=null)){var screenBounds=this.layer.map.getExtent();onScreen=screenBounds.containsLonLat(this.lonlat);}
+return onScreen;},createMarker:function(){if(this.lonlat!=null){this.marker=new OpenLayers.Marker(this.lonlat,this.data.icon);}
+return this.marker;},destroyMarker:function(){this.marker.destroy();},createPopup:function(closeBox){if(this.lonlat!=null){var id=this.id+"_popup";var anchor=(this.marker)?this.marker.icon:null;if(!this.popup){this.popup=new this.popupClass(id,this.lonlat,this.data.popupSize,this.data.popupContentHTML,anchor,closeBox);}
+if(this.data.overflow!=null){this.popup.contentDiv.style.overflow=this.data.overflow;}
+this.popup.feature=this;}
+return this.popup;},destroyPopup:function(){if(this.popup){this.popup.feature=null;this.popup.destroy();this.popup=null;}},CLASS_NAME:"OpenLayers.Feature"});OpenLayers.Format.CSWGetDomain.v2_0_2=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",csw:"http://www.opengis.net/cat/csw/2.0.2"},defaultPrefix:"csw",version:"2.0.2",schemaLocation:"http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd",PropertyName:null,ParameterName:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+if(data&&data.nodeType==9){data=data.documentElement;}
+var obj={};this.readNode(data,obj);return obj;},readers:{"csw":{"GetDomainResponse":function(node,obj){this.readChildNodes(node,obj);},"DomainValues":function(node,obj){if(!(obj.DomainValues instanceof Array)){obj.DomainValues=[];}
+var attrs=node.attributes;var domainValue={};for(var i=0,len=attrs.length;i<len;++i){domainValue[attrs[i].name]=attrs[i].nodeValue;}
+this.readChildNodes(node,domainValue);obj.DomainValues.push(domainValue);},"PropertyName":function(node,obj){obj.PropertyName=this.getChildValue(node);},"ParameterName":function(node,obj){obj.ParameterName=this.getChildValue(node);},"ListOfValues":function(node,obj){if(!(obj.ListOfValues instanceof Array)){obj.ListOfValues=[];}
+this.readChildNodes(node,obj.ListOfValues);},"Value":function(node,obj){var attrs=node.attributes;var value={}
+for(var i=0,len=attrs.length;i<len;++i){value[attrs[i].name]=attrs[i].nodeValue;}
+value.value=this.getChildValue(node);obj.push({Value:value});},"ConceptualScheme":function(node,obj){obj.ConceptualScheme={};this.readChildNodes(node,obj.ConceptualScheme);},"Name":function(node,obj){obj.Name=this.getChildValue(node);},"Document":function(node,obj){obj.Document=this.getChildValue(node);},"Authority":function(node,obj){obj.Authority=this.getChildValue(node);},"RangeOfValues":function(node,obj){obj.RangeOfValues={};this.readChildNodes(node,obj.RangeOfValues);},"MinValue":function(node,obj){var attrs=node.attributes;var value={}
+for(var i=0,len=attrs.length;i<len;++i){value[attrs[i].name]=attrs[i].nodeValue;}
+value.value=this.getChildValue(node);obj.MinValue=value;},"MaxValue":function(node,obj){var attrs=node.attributes;var value={}
+for(var i=0,len=attrs.length;i<len;++i){value[attrs[i].name]=attrs[i].nodeValue;}
+value.value=this.getChildValue(node);obj.MaxValue=value;}}},write:function(options){var node=this.writeNode("csw:GetDomain",options);return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},writers:{"csw":{"GetDomain":function(options){var node=this.createElementNSPlus("csw:GetDomain",{attributes:{service:"CSW",version:this.version}});if(options.PropertyName||this.PropertyName){this.writeNode("csw:PropertyName",options.PropertyName||this.PropertyName,node);}else if(options.ParameterName||this.ParameterName){this.writeNode("csw:ParameterName",options.ParameterName||this.ParameterName,node);}
+this.readChildNodes(node,options);return node;},"PropertyName":function(value){var node=this.createElementNSPlus("csw:PropertyName",{value:value});return node;},"ParameterName":function(value){var node=this.createElementNSPlus("csw:ParameterName",{value:value});return node;}}},CLASS_NAME:"OpenLayers.Format.CSWGetDomain.v2_0_2"});OpenLayers.Format.Context=OpenLayers.Class({version:null,layerOptions:null,layerParams:null,parser:null,initialize:function(options){OpenLayers.Util.extend(this,options);this.options=options;},read:function(data,options){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");}
+var parser=this.getParser(version);var context=parser.read(data,options);var map;if(options&&options.map){this.context=context;if(options.map instanceof OpenLayers.Map){map=this.mergeContextToMap(context,options.map);}else{var mapOptions=options.map;if(OpenLayers.Util.isElement(mapOptions)||typeof mapOptions=="string"){mapOptions={div:mapOptions};}
+map=this.contextToMap(context,mapOptions);}}else{map=context;}
+return map;},getLayerFromContext:function(layerContext){var i,len;var options={queryable:layerContext.queryable,visibility:layerContext.visibility,maxExtent:layerContext.maxExtent,metadata:OpenLayers.Util.applyDefaults(layerContext.metadata,{styles:layerContext.styles}),numZoomLevels:layerContext.numZoomLevels,units:layerContext.units,isBaseLayer:layerContext.isBaseLayer,opacity:layerContext.opacity,displayInLayerSwitcher:layerContext.displayInLayerSwitcher,singleTile:layerContext.singleTile,tileSize:(layerContext.tileSize)?new OpenLayers.Size(layerContext.tileSize.width,layerContext.tileSize.height):undefined,minScale:layerContext.minScale||layerContext.maxScaleDenominator,maxScale:layerContext.maxScale||layerContext.minScaleDenominator};if(this.layerOptions){OpenLayers.Util.applyDefaults(options,this.layerOptions);}
+var params={layers:layerContext.name,transparent:layerContext.transparent,version:layerContext.version};if(layerContext.formats&&layerContext.formats.length>0){params.format=layerContext.formats[0].value;for(i=0,len=layerContext.formats.length;i<len;i++){var format=layerContext.formats[i];if(format.current==true){params.format=format.value;break;}}}
+if(layerContext.styles&&layerContext.styles.length>0){for(i=0,len=layerContext.styles.length;i<len;i++){var style=layerContext.styles[i];if(style.current==true){if(style.href){params.sld=style.href;}else if(style.body){params.sld_body=style.body;}else{params.styles=style.name;}
+break;}}}
+if(this.layerParams){OpenLayers.Util.applyDefaults(params,this.layerParams);}
+var layer=null;var service=layerContext.service;if(service==OpenLayers.Format.Context.serviceTypes.WFS){options.strategies=[new OpenLayers.Strategy.BBOX()];options.protocol=new OpenLayers.Protocol.WFS({url:layerContext.url,featurePrefix:layerContext.name.split(":")[0],featureType:layerContext.name.split(":").pop()});layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);}else if(service==OpenLayers.Format.Context.serviceTypes.KML){options.strategies=[new OpenLayers.Strategy.Fixed()];options.protocol=new OpenLayers.Protocol.HTTP({url:layerContext.url,format:new OpenLayers.Format.KML()});layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);}else if(service==OpenLayers.Format.Context.serviceTypes.GML){options.strategies=[new OpenLayers.Strategy.Fixed()];options.protocol=new OpenLayers.Protocol.HTTP({url:layerContext.url,format:new OpenLayers.Format.GML()});layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);}else if(layerContext.features){layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);layer.addFeatures(layerContext.features);}else if(layerContext.categoryLayer!==true){layer=new OpenLayers.Layer.WMS(layerContext.title||layerContext.name,layerContext.url,params,options);}
+return layer;},getLayersFromContext:function(layersContext){var layers=[];for(var i=0,len=layersContext.length;i<len;i++){var layer=this.getLayerFromContext(layersContext[i]);if(layer!==null){layers.push(layer);}}
+return layers;},contextToMap:function(context,options){options=OpenLayers.Util.applyDefaults({maxExtent:context.maxExtent,projection:context.projection},options);var map=new OpenLayers.Map(options);map.addLayers(this.getLayersFromContext(context.layersContext));map.setCenter(context.bounds.getCenterLonLat(),map.getZoomForExtent(context.bounds,true));return map;},mergeContextToMap:function(context,map){map.addLayers(this.getLayersFromContext(context.layersContext));return map;},write:function(obj,options){obj=this.toContext(obj);var version=options&&options.version;var parser=this.getParser(version);var context=parser.write(obj,options);return context;},CLASS_NAME:"OpenLayers.Format.Context"});OpenLayers.Format.Context.serviceTypes={"WMS":"urn:ogc:serviceType:WMS","WFS":"urn:ogc:serviceType:WFS","WCS":"urn:ogc:serviceType:WCS","GML":"urn:ogc:serviceType:GML","SLD":"urn:ogc:serviceType:SLD","FES":"urn:ogc:serviceType:FES","KML":"urn:ogc:serviceType:KML"};if(!OpenLayers.Format.OWSCommon){OpenLayers.Format.OWSCommon={};}
+OpenLayers.Format.OWSCommon.v1=OpenLayers.Class(OpenLayers.Format.XML,{regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},readers:{"ows":{"ServiceIdentification":function(node,obj){obj.serviceIdentification={};this.readChildNodes(node,obj.serviceIdentification);},"Title":function(node,obj){obj.title=this.getChildValue(node);},"Abstract":function(node,serviceIdentification){serviceIdentification["abstract"]=this.getChildValue(node);},"Keywords":function(node,serviceIdentification){serviceIdentification.keywords={};this.readChildNodes(node,serviceIdentification.keywords);},"Keyword":function(node,keywords){keywords[this.getChildValue(node)]=true;},"ServiceType":function(node,serviceIdentification){serviceIdentification.serviceType={codeSpace:node.getAttribute('codeSpace'),value:this.getChildValue(node)};},"ServiceTypeVersion":function(node,serviceIdentification){serviceIdentification.serviceTypeVersion=this.getChildValue(node);},"Fees":function(node,serviceIdentification){serviceIdentification.fees=this.getChildValue(node);},"AccessConstraints":function(node,serviceIdentification){serviceIdentification.accessConstraints=this.getChildValue(node);},"ServiceProvider":function(node,obj){obj.serviceProvider={};this.readChildNodes(node,obj.serviceProvider);},"ProviderName":function(node,serviceProvider){serviceProvider.providerName=this.getChildValue(node);},"ProviderSite":function(node,serviceProvider){serviceProvider.providerSite=this.getAttributeNS(node,this.namespaces.xlink,"href");},"ServiceContact":function(node,serviceProvider){serviceProvider.serviceContact={};this.readChildNodes(node,serviceProvider.serviceContact);},"IndividualName":function(node,serviceContact){serviceContact.individualName=this.getChildValue(node);},"PositionName":function(node,serviceContact){serviceContact.positionName=this.getChildValue(node);},"ContactInfo":function(node,serviceContact){serviceContact.contactInfo={};this.readChildNodes(node,serviceContact.contactInfo);},"Phone":function(node,contactInfo){contactInfo.phone={};this.readChildNodes(node,contactInfo.phone);},"Voice":function(node,phone){phone.voice=this.getChildValue(node);},"Address":function(node,contactInfo){contactInfo.address={};this.readChildNodes(node,contactInfo.address);},"DeliveryPoint":function(node,address){address.deliveryPoint=this.getChildValue(node);},"City":function(node,address){address.city=this.getChildValue(node);},"AdministrativeArea":function(node,address){address.administrativeArea=this.getChildValue(node);},"PostalCode":function(node,address){address.postalCode=this.getChildValue(node);},"Country":function(node,address){address.country=this.getChildValue(node);},"ElectronicMailAddress":function(node,address){address.electronicMailAddress=this.getChildValue(node);},"Role":function(node,serviceContact){serviceContact.role=this.getChildValue(node);},"OperationsMetadata":function(node,obj){obj.operationsMetadata={};this.readChildNodes(node,obj.operationsMetadata);},"Operation":function(node,operationsMetadata){var name=node.getAttribute("name");operationsMetadata[name]={};this.readChildNodes(node,operationsMetadata[name]);},"DCP":function(node,operation){operation.dcp={};this.readChildNodes(node,operation.dcp);},"HTTP":function(node,dcp){dcp.http={};this.readChildNodes(node,dcp.http);},"Get":function(node,http){http.get=this.getAttributeNS(node,this.namespaces.xlink,"href");},"Post":function(node,http){http.post=this.getAttributeNS(node,this.namespaces.xlink,"href");},"Parameter":function(node,operation){if(!operation.parameters){operation.parameters={};}
+var name=node.getAttribute("name");operation.parameters[name]={};this.readChildNodes(node,operation.parameters[name]);},"Value":function(node,allowedValues){allowedValues[this.getChildValue(node)]=true;},"OutputFormat":function(node,obj){obj.formats.push({value:this.getChildValue(node)});this.readChildNodes(node,obj);},"WGS84BoundingBox":function(node,obj){var boundingBox={};boundingBox.crs=node.getAttribute("crs");if(obj.BoundingBox){obj.BoundingBox.push(boundingBox);}else{obj.projection=boundingBox.crs;boundingBox=obj;}
+this.readChildNodes(node,boundingBox);},"BoundingBox":function(node,obj){this.readers['ows']['WGS84BoundingBox'].apply(this,[node,obj]);},"LowerCorner":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");str=str.replace(this.regExes.trimComma,",");var pointList=str.split(this.regExes.splitSpace);obj.left=pointList[0];obj.bottom=pointList[1];},"UpperCorner":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");str=str.replace(this.regExes.trimComma,",");var pointList=str.split(this.regExes.splitSpace);obj.right=pointList[0];obj.top=pointList[1];obj.bounds=new OpenLayers.Bounds(obj.left,obj.bottom,obj.right,obj.top);delete obj.left;delete obj.bottom;delete obj.right;delete obj.top;}}},writers:{"ows":{"BoundingBox":function(options){var node=this.createElementNSPlus("ows:BoundingBox",{attributes:{crs:options.projection}});this.writeNode("ows:LowerCorner",options,node);this.writeNode("ows:UpperCorner",options,node);return node;},"LowerCorner":function(options){var node=this.createElementNSPlus("ows:LowerCorner",{value:options.bounds.left+" "+options.bounds.bottom});return node;},"UpperCorner":function(options){var node=this.createElementNSPlus("ows:UpperCorner",{value:options.bounds.right+" "+options.bounds.top});return node;},"Title":function(title){var node=this.createElementNSPlus("ows:Title",{value:title});return node;},"OutputFormat":function(format){var node=this.createElementNSPlus("ows:OutputFormat",{value:format});return node;}}},CLASS_NAME:"OpenLayers.Format.OWSCommon.v1"});OpenLayers.Format.SOSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var root=data.documentElement;var version=this.version||root.getAttribute("version")||this.defaultVersion;if(!this.parser||this.parser.version!==version){var constr=OpenLayers.Format.SOSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw"Can't find a SOS capabilities parser for version "+version;}
+var parser=new constr(this.options);}
+var capabilities=parser.read(data);capabilities.version=version;return capabilities;},CLASS_NAME:"OpenLayers.Format.SOSCapabilities"});OpenLayers.Format.WFSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.1.0",version:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");if(!version){version=this.defaultVersion;}}
+var constr=OpenLayers.Format.WFSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw"Can't find a WFS capabilities parser for version "+version;}
+var parser=new constr(this.options);var capabilities=parser.read(data);capabilities.version=version;return capabilities;},CLASS_NAME:"OpenLayers.Format.WFSCapabilities"});OpenLayers.Format.WFSDescribeFeatureType=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xsd:"http://www.w3.org/2001/XMLSchema"},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},readers:{"xsd":{"schema":function(node,obj){var complexTypes=[];var customTypes={};var schema={complexTypes:complexTypes,customTypes:customTypes};this.readChildNodes(node,schema);var attributes=node.attributes;var attr,name;for(var i=0,len=attributes.length;i<len;++i){attr=attributes[i];name=attr.name;if(name.indexOf("xmlns")==0){this.setNamespace(name.split(":")[1]||"",attr.value);}else{obj[name]=attr.value;}}
+obj.featureTypes=complexTypes;obj.targetPrefix=this.namespaceAlias[obj.targetNamespace];var complexType,customType;for(var i=0,len=complexTypes.length;i<len;++i){complexType=complexTypes[i];customType=customTypes[complexType.typeName];if(customTypes[complexType.typeName]){complexType.typeName=customType.name;}}},"complexType":function(node,obj){var complexType={"typeName":node.getAttribute("name")};this.readChildNodes(node,complexType);obj.complexTypes.push(complexType);},"complexContent":function(node,obj){this.readChildNodes(node,obj);},"extension":function(node,obj){this.readChildNodes(node,obj);},"sequence":function(node,obj){var sequence={elements:[]};this.readChildNodes(node,sequence);obj.properties=sequence.elements;},"element":function(node,obj){if(obj.elements){var element={};var attributes=node.attributes;var attr;for(var i=0,len=attributes.length;i<len;++i){attr=attributes[i];element[attr.name]=attr.value;}
+var type=element.type;if(!type){type={};this.readChildNodes(node,type);element.restriction=type;element.type=type.base;}
+var fullType=type.base||type;element.localType=fullType.split(":").pop();obj.elements.push(element);}
+if(obj.complexTypes){var type=node.getAttribute("type");var localType=type.split(":").pop();obj.customTypes[localType]={"name":node.getAttribute("name"),"type":type};}},"simpleType":function(node,obj){this.readChildNodes(node,obj);},"restriction":function(node,obj){obj.base=node.getAttribute("base");this.readRestriction(node,obj);}}},readRestriction:function(node,obj){var children=node.childNodes;var child,nodeName,value;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){nodeName=child.nodeName.split(":").pop();value=child.getAttribute("value");if(!obj[nodeName]){obj[nodeName]=value;}else{if(typeof obj[nodeName]=="string"){obj[nodeName]=[obj[nodeName]];}
+obj[nodeName].push(value);}}}},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+if(data&&data.nodeType==9){data=data.documentElement;}
+var schema={};this.readNode(data,schema);return schema;},CLASS_NAME:"OpenLayers.Format.WFSDescribeFeatureType"});OpenLayers.Format.WFST.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",wfs:"http://www.opengis.net/wfs",gml:"http://www.opengis.net/gml",ogc:"http://www.opengis.net/ogc"},defaultPrefix:"wfs",version:null,schemaLocations:null,srsName:null,extractAttributes:true,xy:true,stateName:null,initialize:function(options){this.stateName={};this.stateName[OpenLayers.State.INSERT]="wfs:Insert";this.stateName[OpenLayers.State.UPDATE]="wfs:Update";this.stateName[OpenLayers.State.DELETE]="wfs:Delete";OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},getSrsName:function(feature,options){var srsName=options&&options.srsName;if(!srsName){if(feature&&feature.layer){srsName=feature.layer.projection.getCode();}else{srsName=this.srsName;}}
+return srsName;},read:function(data,options){options=options||{};OpenLayers.Util.applyDefaults(options,{output:"features"});if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+if(data&&data.nodeType==9){data=data.documentElement;}
+var obj={};if(data){this.readNode(data,obj);}
+if(obj.features&&options.output==="features"){obj=obj.features;}
+return obj;},readers:{"wfs":{"FeatureCollection":function(node,obj){obj.features=[];this.readChildNodes(node,obj);}}},write:function(features){var node=this.writeNode("wfs:Transaction",features);var value=this.schemaLocationAttr();if(value){this.setAttributeNS(node,this.namespaces["xsi"],"xsi:schemaLocation",value)}
+return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},writers:{"wfs":{"GetFeature":function(options){var node=this.createElementNSPlus("wfs:GetFeature",{attributes:{service:"WFS",version:this.version,outputFormat:options&&options.outputFormat,maxFeatures:options&&options.maxFeatures,"xsi:schemaLocation":this.schemaLocationAttr(options)}});if(typeof this.featureType=="string"){this.writeNode("Query",options,node);}else{for(var i=0,len=this.featureType.length;i<len;i++){options.featureType=this.featureType[i];this.writeNode("Query",options,node);}}
+return node;},"Transaction":function(features){var node=this.createElementNSPlus("wfs:Transaction",{attributes:{service:"WFS",version:this.version}});if(features){var name,feature;for(var i=0,len=features.length;i<len;++i){feature=features[i];name=this.stateName[feature.state];if(name){this.writeNode(name,feature,node);}}}
+return node;},"Insert":function(feature){var node=this.createElementNSPlus("wfs:Insert");this.srsName=this.getSrsName(feature);this.writeNode("feature:_typeName",feature,node);return node;},"Update":function(feature){var node=this.createElementNSPlus("wfs:Update",{attributes:{typeName:(this.featureNS?this.featurePrefix+":":"")+
+this.featureType}});if(this.featureNS){node.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);}
+if(this.geometryName!==null){this.writeNode("Property",{name:this.geometryName,value:feature},node);}
+for(var key in feature.attributes){if(feature.attributes[key]!==undefined){this.writeNode("Property",{name:key,value:feature.attributes[key]},node);}}
+this.writeNode("ogc:Filter",new OpenLayers.Filter.FeatureId({fids:[feature.fid]}),node);return node;},"Property":function(obj){var node=this.createElementNSPlus("wfs:Property");this.writeNode("Name",obj.name,node);if(obj.value!==null){this.writeNode("Value",obj.value,node);}
+return node;},"Name":function(name){return this.createElementNSPlus("wfs:Name",{value:name});},"Value":function(obj){var node;if(obj instanceof OpenLayers.Feature.Vector){node=this.createElementNSPlus("wfs:Value");this.srsName=this.getSrsName(obj);var geom=this.writeNode("feature:_geometry",obj.geometry).firstChild;node.appendChild(geom);}else{node=this.createElementNSPlus("wfs:Value",{value:obj});}
+return node;},"Delete":function(feature){var node=this.createElementNSPlus("wfs:Delete",{attributes:{typeName:(this.featureNS?this.featurePrefix+":":"")+
+this.featureType}});if(this.featureNS){node.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);}
+this.writeNode("ogc:Filter",new OpenLayers.Filter.FeatureId({fids:[feature.fid]}),node);return node;}}},schemaLocationAttr:function(options){options=OpenLayers.Util.extend({featurePrefix:this.featurePrefix,schema:this.schema},options);var schemaLocations=OpenLayers.Util.extend({},this.schemaLocations);if(options.schema){schemaLocations[options.featurePrefix]=options.schema;}
+var parts=[];var uri;for(var key in schemaLocations){uri=this.namespaces[key];if(uri){parts.push(uri+" "+schemaLocations[key]);}}
+var value=parts.join(" ")||undefined;return value;},setFilterProperty:function(filter){if(filter.filters){for(var i=0,len=filter.filters.length;i<len;++i){this.setFilterProperty(filter.filters[i]);}}else{if(filter instanceof OpenLayers.Filter.Spatial){filter.property=this.geometryName;}}},CLASS_NAME:"OpenLayers.Format.WFST.v1"});OpenLayers.Format.WMSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.1.1",version:null,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var root=data.documentElement;var version=this.version||root.getAttribute("version")||this.defaultVersion;if(!this.parser||this.parser.version!==version){var constr=OpenLayers.Format.WMSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw"Can't find a WMS capabilities parser for version "+version;}
+this.parser=new constr(this.options);}
+var capabilities=this.parser.read(data);capabilities.version=version;return capabilities;},CLASS_NAME:"OpenLayers.Format.WMSCapabilities"});OpenLayers.Format.WMSDescribeLayer=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.1.1",version:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");if(!version){version=this.defaultVersion;}}
+if(version=="1.1.1"||version=="1.1.0"){version="1.1";}
+var constructor=OpenLayers.Format.WMSDescribeLayer["v"+version.replace(/\./g,"_")];if(!constructor){throw"Can't find a WMS DescribeLayer parser for version "+
+version;}
+var parser=new constructor(this.options);var describelayer=parser.read(data);describelayer.version=version;return describelayer;},CLASS_NAME:"OpenLayers.Format.WMSDescribeLayer"});OpenLayers.Format.WMSGetFeatureInfo=OpenLayers.Class(OpenLayers.Format.XML,{layerIdentifier:'_layer',featureIdentifier:'_feature',regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},gmlFormat:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,arguments);OpenLayers.Util.extend(this,options);this.options=options;},read:function(data){var result;if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var root=data.documentElement;if(root){var scope=this;var read=this["read_"+root.nodeName];if(read){result=read.call(this,root);}else{result=new OpenLayers.Format.GML((this.options?this.options:{})).read(data);}}else{result=data;}
+return result;},read_msGMLOutput:function(data){var response=[];var layerNodes=this.getSiblingNodesByTagCriteria(data,this.layerIdentifier);if(layerNodes){for(var i=0,len=layerNodes.length;i<len;++i){var node=layerNodes[i];var layerName=node.nodeName;if(node.prefix){layerName=layerName.split(':')[1];}
+var layerName=layerName.replace(this.layerIdentifier,'');var featureNodes=this.getSiblingNodesByTagCriteria(node,this.featureIdentifier);if(featureNodes){for(var j=0;j<featureNodes.length;j++){var featureNode=featureNodes[j];var geomInfo=this.parseGeometry(featureNode);var attributes=this.parseAttributes(featureNode);var feature=new OpenLayers.Feature.Vector(geomInfo.geometry,attributes,null);feature.bounds=geomInfo.bounds;feature.type=layerName;response.push(feature);}}}}
+return response;},read_FeatureInfoResponse:function(data){var response=[];var featureNodes=this.getElementsByTagNameNS(data,'*','FIELDS');for(var i=0,len=featureNodes.length;i<len;i++){var featureNode=featureNodes[i];var geom=null;var attributes={};for(var j=0,jlen=featureNode.attributes.length;j<jlen;j++){var attribute=featureNode.attributes[j];attributes[attribute.nodeName]=attribute.nodeValue;}
+response.push(new OpenLayers.Feature.Vector(geom,attributes,null));}
+return response;},getSiblingNodesByTagCriteria:function(node,criteria){var nodes=[];var children,tagName,n,matchNodes,child;if(node&&node.hasChildNodes()){children=node.childNodes;n=children.length;for(var k=0;k<n;k++){child=children[k];while(child&&child.nodeType!=1){child=child.nextSibling;k++;}
+tagName=(child?child.nodeName:'');if(tagName.length>0&&tagName.indexOf(criteria)>-1){nodes.push(child);}else{matchNodes=this.getSiblingNodesByTagCriteria(child,criteria);if(matchNodes.length>0){(nodes.length==0)?nodes=matchNodes:nodes.push(matchNodes);}}}}
+return nodes;},parseAttributes:function(node){var attributes={};if(node.nodeType==1){var children=node.childNodes;var n=children.length;for(var i=0;i<n;++i){var child=children[i];if(child.nodeType==1){var grandchildren=child.childNodes;if(grandchildren.length==1){var grandchild=grandchildren[0];if(grandchild.nodeType==3||grandchild.nodeType==4){var name=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;var value=grandchild.nodeValue.replace(this.regExes.trimSpace,"");attributes[name]=value;}}}}}
+return attributes;},parseGeometry:function(node){if(!this.gmlFormat){this.gmlFormat=new OpenLayers.Format.GML();}
+var feature=this.gmlFormat.parseFeature(node);var geometry,bounds=null;if(feature){geometry=feature.geometry&&feature.geometry.clone();bounds=feature.bounds&&feature.bounds.clone();feature.destroy();}
+return{geometry:geometry,bounds:bounds};},CLASS_NAME:"OpenLayers.Format.WMSGetFeatureInfo"});OpenLayers.Format.WMTSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,parser:null,yx:{"urn:ogc:def:crs:EPSG::4326":true},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var root=data.documentElement;var version=this.version||root.getAttribute("version")||this.defaultVersion;if(!this.parser||this.parser.version!==version){var constr=OpenLayers.Format.WMTSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw new Error("Can't find a WMTS capabilities parser for version "+version);}
+this.parser=new constr(this.options);}
+return this.parser.read(data);},createLayer:function(capabilities,config){var layer;var required={layer:true,matrixSet:true};for(var prop in required){if(!(prop in config)){throw new Error("Missing property '"+prop+"' in layer configuration.");}}
+var contents=capabilities.contents;var matrixSet=contents.tileMatrixSets[config.matrixSet];var layers=contents.layers;var layerDef;for(var i=0,ii=contents.layers.length;i<ii;++i){if(contents.layers[i].identifier===config.layer){layerDef=contents.layers[i];break;}}
+if(layerDef&&matrixSet){var style;for(var i=0,ii=layerDef.styles.length;i<ii;++i){style=layerDef.styles[i];if(style.isDefault){break;}}
+layer=new OpenLayers.Layer.WMTS(OpenLayers.Util.applyDefaults(config,{url:capabilities.operationsMetadata.GetTile.dcp.http.get,name:layerDef.title,style:style,matrixIds:matrixSet.matrixIds}));}
+return layer;},CLASS_NAME:"OpenLayers.Format.WMTSCapabilities"});OpenLayers.Handler.Click=OpenLayers.Class(OpenLayers.Handler,{delay:300,single:true,'double':false,pixelTolerance:0,stopSingle:false,stopDouble:false,timerId:null,down:null,rightclickTimerId:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);if(this.pixelTolerance!=null){this.mousedown=function(evt){this.down=evt.xy;return true;};}},mousedown:null,mouseup:function(evt){var propagate=true;if(this.checkModifiers(evt)&&this.control.handleRightClicks&&OpenLayers.Event.isRightClick(evt)){propagate=this.rightclick(evt);}
+return propagate;},rightclick:function(evt){if(this.passesTolerance(evt)){if(this.rightclickTimerId!=null){this.clearTimer();this.callback('dblrightclick',[evt]);return!this.stopDouble;}else{var clickEvent=this['double']?OpenLayers.Util.extend({},evt):this.callback('rightclick',[evt]);var delayedRightCall=OpenLayers.Function.bind(this.delayedRightCall,this,clickEvent);this.rightclickTimerId=window.setTimeout(delayedRightCall,this.delay);}}
+return!this.stopSingle;},delayedRightCall:function(evt){this.rightclickTimerId=null;if(evt){this.callback('rightclick',[evt]);}
+return!this.stopSingle;},dblclick:function(evt){if(this.passesTolerance(evt)){if(this["double"]){this.callback('dblclick',[evt]);}
+this.clearTimer();}
+return!this.stopDouble;},click:function(evt){if(this.passesTolerance(evt)){if(this.timerId!=null){this.clearTimer();}else{var clickEvent=this.single?OpenLayers.Util.extend({},evt):null;this.timerId=window.setTimeout(OpenLayers.Function.bind(this.delayedCall,this,clickEvent),this.delay);}}
+return!this.stopSingle;},passesTolerance:function(evt){var passes=true;if(this.pixelTolerance!=null&&this.down){var dpx=Math.sqrt(Math.pow(this.down.x-evt.xy.x,2)+
+Math.pow(this.down.y-evt.xy.y,2));if(dpx>this.pixelTolerance){passes=false;}}
+return passes;},clearTimer:function(){if(this.timerId!=null){window.clearTimeout(this.timerId);this.timerId=null;}
+if(this.rightclickTimerId!=null){window.clearTimeout(this.rightclickTimerId);this.rightclickTimerId=null;}},delayedCall:function(evt){this.timerId=null;if(evt){this.callback('click',[evt]);}},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.clearTimer();this.down=null;deactivated=true;}
+return deactivated;},CLASS_NAME:"OpenLayers.Handler.Click"});OpenLayers.Handler.Drag=OpenLayers.Class(OpenLayers.Handler,{started:false,stopDown:true,dragging:false,last:null,start:null,oldOnselectstart:null,interval:0,timeoutId:null,documentDrag:false,documentEvents:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);},down:function(evt){},move:function(evt){},up:function(evt){},out:function(evt){},mousedown:function(evt){var propagate=true;this.dragging=false;if(this.checkModifiers(evt)&&OpenLayers.Event.isLeftClick(evt)){this.started=true;this.start=evt.xy;this.last=evt.xy;OpenLayers.Element.addClass(this.map.viewPortDiv,"olDragDown");this.down(evt);this.callback("down",[evt.xy]);OpenLayers.Event.stop(evt);if(!this.oldOnselectstart){this.oldOnselectstart=(document.onselectstart)?document.onselectstart:OpenLayers.Function.True;}
+document.onselectstart=OpenLayers.Function.False;propagate=!this.stopDown;}else{this.started=false;this.start=null;this.last=null;}
+return propagate;},mousemove:function(evt){if(this.started&&!this.timeoutId&&(evt.xy.x!=this.last.x||evt.xy.y!=this.last.y)){if(this.documentDrag===true&&this.documentEvents){if(evt.element===document){this.adjustXY(evt);this.setEvent(evt);}else{this.destroyDocumentEvents();}}
+if(this.interval>0){this.timeoutId=setTimeout(OpenLayers.Function.bind(this.removeTimeout,this),this.interval);}
+this.dragging=true;this.move(evt);this.callback("move",[evt.xy]);if(!this.oldOnselectstart){this.oldOnselectstart=document.onselectstart;document.onselectstart=OpenLayers.Function.False;}
+this.last=this.evt.xy;}
+return true;},removeTimeout:function(){this.timeoutId=null;},mouseup:function(evt){if(this.started){if(this.documentDrag===true&&this.documentEvents){this.adjustXY(evt);this.destroyDocumentEvents();}
+var dragged=(this.start!=this.last);this.started=false;this.dragging=false;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");this.up(evt);this.callback("up",[evt.xy]);if(dragged){this.callback("done",[evt.xy]);}
+document.onselectstart=this.oldOnselectstart;}
+return true;},mouseout:function(evt){if(this.started&&OpenLayers.Util.mouseLeft(evt,this.map.div)){if(this.documentDrag===true){this.documentEvents=new OpenLayers.Events(this,document,null,null,{includeXY:true});this.documentEvents.on({mousemove:this.mousemove,mouseup:this.mouseup});OpenLayers.Element.addClass(document.body,"olDragDown");}else{var dragged=(this.start!=this.last);this.started=false;this.dragging=false;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");this.out(evt);this.callback("out",[]);if(dragged){this.callback("done",[evt.xy]);}
+if(document.onselectstart){document.onselectstart=this.oldOnselectstart;}}}
+return true;},click:function(evt){return(this.start==this.last);},activate:function(){var activated=false;if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){this.dragging=false;activated=true;}
+return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.started=false;this.dragging=false;this.start=null;this.last=null;deactivated=true;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");}
+return deactivated;},adjustXY:function(evt){var pos=OpenLayers.Util.pagePosition(this.map.div);evt.xy.x-=pos[0];evt.xy.y-=pos[1];},destroyDocumentEvents:function(){OpenLayers.Element.removeClass(document.body,"olDragDown");this.documentEvents.destroy();this.documentEvents=null;},CLASS_NAME:"OpenLayers.Handler.Drag"});OpenLayers.Handler.Feature=OpenLayers.Class(OpenLayers.Handler,{EVENTMAP:{'click':{'in':'click','out':'clickout'},'mousemove':{'in':'over','out':'out'},'dblclick':{'in':'dblclick','out':null},'mousedown':{'in':null,'out':null},'mouseup':{'in':null,'out':null}},feature:null,lastFeature:null,down:null,up:null,clickTolerance:4,geometryTypes:null,stopClick:true,stopDown:true,stopUp:false,initialize:function(control,layer,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,[control,callbacks,options]);this.layer=layer;},mousedown:function(evt){this.down=evt.xy;return this.handle(evt)?!this.stopDown:true;},mouseup:function(evt){this.up=evt.xy;return this.handle(evt)?!this.stopUp:true;},click:function(evt){return this.handle(evt)?!this.stopClick:true;},mousemove:function(evt){if(!this.callbacks['over']&&!this.callbacks['out']){return true;}
+this.handle(evt);return true;},dblclick:function(evt){return!this.handle(evt);},geometryTypeMatches:function(feature){return this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)>-1;},handle:function(evt){if(this.feature&&!this.feature.layer){this.feature=null;}
+var type=evt.type;var handled=false;var previouslyIn=!!(this.feature);var click=(type=="click"||type=="dblclick");this.feature=this.layer.getFeatureFromEvent(evt);if(this.feature&&!this.feature.layer){this.feature=null;}
+if(this.lastFeature&&!this.lastFeature.layer){this.lastFeature=null;}
+if(this.feature){var inNew=(this.feature!=this.lastFeature);if(this.geometryTypeMatches(this.feature)){if(previouslyIn&&inNew){if(this.lastFeature){this.triggerCallback(type,'out',[this.lastFeature]);}
+this.triggerCallback(type,'in',[this.feature]);}else if(!previouslyIn||click){this.triggerCallback(type,'in',[this.feature]);}
+this.lastFeature=this.feature;handled=true;}else{if(this.lastFeature&&(previouslyIn&&inNew||click)){this.triggerCallback(type,'out',[this.lastFeature]);}
+this.feature=null;}}else{if(this.lastFeature&&(previouslyIn||click)){this.triggerCallback(type,'out',[this.lastFeature]);}}
+return handled;},triggerCallback:function(type,mode,args){var key=this.EVENTMAP[type][mode];if(key){if(type=='click'&&this.up&&this.down){var dpx=Math.sqrt(Math.pow(this.up.x-this.down.x,2)+
+Math.pow(this.up.y-this.down.y,2));if(dpx<=this.clickTolerance){this.callback(key,args);}}else{this.callback(key,args);}}},activate:function(){var activated=false;if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){this.moveLayerToTop();this.map.events.on({"removelayer":this.handleMapEvents,"changelayer":this.handleMapEvents,scope:this});activated=true;}
+return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.moveLayerBack();this.feature=null;this.lastFeature=null;this.down=null;this.up=null;this.map.events.un({"removelayer":this.handleMapEvents,"changelayer":this.handleMapEvents,scope:this});deactivated=true;}
+return deactivated;},handleMapEvents:function(evt){if(!evt.property||evt.property=="order"){this.moveLayerToTop();}},moveLayerToTop:function(){var index=Math.max(this.map.Z_INDEX_BASE['Feature']-1,this.layer.getZIndex())+1;this.layer.setZIndex(index);},moveLayerBack:function(){var index=this.layer.getZIndex()-1;if(index>=this.map.Z_INDEX_BASE['Feature']){this.layer.setZIndex(index);}else{this.map.setLayerZIndex(this.layer,this.map.getLayerIndex(this.layer));}},CLASS_NAME:"OpenLayers.Handler.Feature"});OpenLayers.Handler.Hover=OpenLayers.Class(OpenLayers.Handler,{delay:500,pixelTolerance:null,stopMove:false,px:null,timerId:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);},mousemove:function(evt){if(this.passesTolerance(evt.xy)){this.clearTimer();this.callback('move',[evt]);this.px=evt.xy;evt=OpenLayers.Util.extend({},evt);this.timerId=window.setTimeout(OpenLayers.Function.bind(this.delayedCall,this,evt),this.delay);}
+return!this.stopMove;},mouseout:function(evt){if(OpenLayers.Util.mouseLeft(evt,this.map.div)){this.clearTimer();this.callback('move',[evt]);}
+return true;},passesTolerance:function(px){var passes=true;if(this.pixelTolerance&&this.px){var dpx=Math.sqrt(Math.pow(this.px.x-px.x,2)+
+Math.pow(this.px.y-px.y,2));if(dpx<this.pixelTolerance){passes=false;}}
+return passes;},clearTimer:function(){if(this.timerId!=null){window.clearTimeout(this.timerId);this.timerId=null;}},delayedCall:function(evt){this.callback('pause',[evt]);},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.clearTimer();deactivated=true;}
+return deactivated;},CLASS_NAME:"OpenLayers.Handler.Hover"});OpenLayers.Handler.Keyboard=OpenLayers.Class(OpenLayers.Handler,{KEY_EVENTS:["keydown","keyup"],eventListener:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);this.eventListener=OpenLayers.Function.bindAsEventListener(this.handleKeyEvent,this);},destroy:function(){this.deactivate();this.eventListener=null;OpenLayers.Handler.prototype.destroy.apply(this,arguments);},activate:function(){if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){for(var i=0,len=this.KEY_EVENTS.length;i<len;i++){OpenLayers.Event.observe(document,this.KEY_EVENTS[i],this.eventListener);}
+return true;}else{return false;}},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){for(var i=0,len=this.KEY_EVENTS.length;i<len;i++){OpenLayers.Event.stopObserving(document,this.KEY_EVENTS[i],this.eventListener);}
+deactivated=true;}
+return deactivated;},handleKeyEvent:function(evt){if(this.checkModifiers(evt)){this.callback(evt.type,[evt]);}},CLASS_NAME:"OpenLayers.Handler.Keyboard"});OpenLayers.Handler.MouseWheel=OpenLayers.Class(OpenLayers.Handler,{wheelListener:null,mousePosition:null,interval:0,delta:0,cumulative:true,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);this.wheelListener=OpenLayers.Function.bindAsEventListener(this.onWheelEvent,this);},destroy:function(){OpenLayers.Handler.prototype.destroy.apply(this,arguments);this.wheelListener=null;},onWheelEvent:function(e){if(!this.map||!this.checkModifiers(e)){return;}
+var overScrollableDiv=false;var overLayerDiv=false;var overMapDiv=false;var elem=OpenLayers.Event.element(e);while((elem!=null)&&!overMapDiv&&!overScrollableDiv){if(!overScrollableDiv){try{if(elem.currentStyle){overflow=elem.currentStyle["overflow"];}else{var style=document.defaultView.getComputedStyle(elem,null);var overflow=style.getPropertyValue("overflow");}
+overScrollableDiv=(overflow&&(overflow=="auto")||(overflow=="scroll"));}catch(err){}}
+if(!overLayerDiv){for(var i=0,len=this.map.layers.length;i<len;i++){if(elem==this.map.layers[i].div||elem==this.map.layers[i].pane){overLayerDiv=true;break;}}}
+overMapDiv=(elem==this.map.div);elem=elem.parentNode;}
+if(!overScrollableDiv&&overMapDiv){if(overLayerDiv){var delta=0;if(!e){e=window.event;}
+if(e.wheelDelta){delta=e.wheelDelta/120;if(window.opera&&window.opera.version()<9.2){delta=-delta;}}else if(e.detail){delta=-e.detail/3;}
+this.delta=this.delta+delta;if(this.interval){window.clearTimeout(this._timeoutId);this._timeoutId=window.setTimeout(OpenLayers.Function.bind(function(){this.wheelZoom(e);},this),this.interval);}else{this.wheelZoom(e);}}
+OpenLayers.Event.stop(e);}},wheelZoom:function(e){var delta=this.delta;this.delta=0;if(delta){if(this.mousePosition){e.xy=this.mousePosition;}
+if(!e.xy){e.xy=this.map.getPixelFromLonLat(this.map.getCenter());}
+if(delta<0){this.callback("down",[e,this.cumulative?delta:-1]);}else{this.callback("up",[e,this.cumulative?delta:1]);}}},mousemove:function(evt){this.mousePosition=evt.xy;},activate:function(evt){if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){var wheelListener=this.wheelListener;OpenLayers.Event.observe(window,"DOMMouseScroll",wheelListener);OpenLayers.Event.observe(window,"mousewheel",wheelListener);OpenLayers.Event.observe(document,"mousewheel",wheelListener);return true;}else{return false;}},deactivate:function(evt){if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){var wheelListener=this.wheelListener;OpenLayers.Event.stopObserving(window,"DOMMouseScroll",wheelListener);OpenLayers.Event.stopObserving(window,"mousewheel",wheelListener);OpenLayers.Event.stopObserving(document,"mousewheel",wheelListener);return true;}else{return false;}},CLASS_NAME:"OpenLayers.Handler.MouseWheel"});OpenLayers.Layer=OpenLayers.Class({id:null,name:null,div:null,opacity:null,alwaysInRange:null,EVENT_TYPES:["loadstart","loadend","loadcancel","visibilitychanged","move","moveend"],RESOLUTION_PROPERTIES:['scales','resolutions','maxScale','minScale','maxResolution','minResolution','numZoomLevels','maxZoomLevel'],events:null,map:null,isBaseLayer:false,alpha:false,displayInLayerSwitcher:true,visibility:true,attribution:null,inRange:false,imageSize:null,imageOffset:null,options:null,eventListeners:null,gutter:0,projection:null,units:null,scales:null,resolutions:null,maxExtent:null,minExtent:null,maxResolution:null,minResolution:null,numZoomLevels:null,minScale:null,maxScale:null,displayOutsideMaxExtent:false,wrapDateLine:false,transitionEffect:null,SUPPORTED_TRANSITIONS:['resize'],metadata:{},initialize:function(name,options){this.addOptions(options);this.name=name;if(this.id==null){this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");this.div=OpenLayers.Util.createDiv(this.id);this.div.style.width="100%";this.div.style.height="100%";this.div.dir="ltr";this.events=new OpenLayers.Events(this,this.div,this.EVENT_TYPES);if(this.eventListeners instanceof Object){this.events.on(this.eventListeners);}}
+if(this.wrapDateLine){this.displayOutsideMaxExtent=true;}},destroy:function(setNewBaseLayer){if(setNewBaseLayer==null){setNewBaseLayer=true;}
+if(this.map!=null){this.map.removeLayer(this,setNewBaseLayer);}
+this.projection=null;this.map=null;this.name=null;this.div=null;this.options=null;if(this.events){if(this.eventListeners){this.events.un(this.eventListeners);}
+this.events.destroy();}
+this.eventListeners=null;this.events=null;},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer(this.name,this.getOptions());}
+OpenLayers.Util.applyDefaults(obj,this);obj.map=null;return obj;},getOptions:function(){var options={};for(var o in this.options){options[o]=this[o];}
+return options;},setName:function(newName){if(newName!=this.name){this.name=newName;if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"name"});}}},addOptions:function(newOptions){if(this.options==null){this.options={};}
+OpenLayers.Util.extend(this.options,newOptions);OpenLayers.Util.extend(this,newOptions);if(typeof this.projection=="string"){this.projection=new OpenLayers.Projection(this.projection);}
+if(this.projection&&this.projection.getUnits()){this.units=this.projection.getUnits();}
+if(this.map){var properties=this.RESOLUTION_PROPERTIES.concat(["projection","units","minExtent","maxExtent"]);for(var o in newOptions){if(newOptions.hasOwnProperty(o)&&OpenLayers.Util.indexOf(properties,o)>=0){this.initResolutions();break;}}}},onMapResize:function(){},redraw:function(){var redrawn=false;if(this.map){this.inRange=this.calculateInRange();var extent=this.getExtent();if(extent&&this.inRange&&this.visibility){var zoomChanged=true;this.moveTo(extent,zoomChanged,false);this.events.triggerEvent("moveend",{"zoomChanged":zoomChanged});redrawn=true;}}
+return redrawn;},moveTo:function(bounds,zoomChanged,dragging){var display=this.visibility;if(!this.isBaseLayer){display=display&&this.inRange;}
+this.display(display);},setMap:function(map){if(this.map==null){this.map=map;this.maxExtent=this.maxExtent||this.map.maxExtent;this.minExtent=this.minExtent||this.map.minExtent;this.projection=this.projection||this.map.projection;if(typeof this.projection=="string"){this.projection=new OpenLayers.Projection(this.projection);}
+this.units=this.projection.getUnits()||this.units||this.map.units;this.initResolutions();if(!this.isBaseLayer){this.inRange=this.calculateInRange();var show=((this.visibility)&&(this.inRange));this.div.style.display=show?"":"none";}
+this.setTileSize();}},afterAdd:function(){},removeMap:function(map){},getImageSize:function(bounds){return(this.imageSize||this.tileSize);},setTileSize:function(size){var tileSize=(size)?size:((this.tileSize)?this.tileSize:this.map.getTileSize());this.tileSize=tileSize;if(this.gutter){this.imageOffset=new OpenLayers.Pixel(-this.gutter,-this.gutter);this.imageSize=new OpenLayers.Size(tileSize.w+(2*this.gutter),tileSize.h+(2*this.gutter));}},getVisibility:function(){return this.visibility;},setVisibility:function(visibility){if(visibility!=this.visibility){this.visibility=visibility;this.display(visibility);this.redraw();if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"visibility"});}
+this.events.triggerEvent("visibilitychanged");}},display:function(display){if(display!=(this.div.style.display!="none")){this.div.style.display=(display&&this.calculateInRange())?"block":"none";}},calculateInRange:function(){var inRange=false;if(this.alwaysInRange){inRange=true;}else{if(this.map){var resolution=this.map.getResolution();inRange=((resolution>=this.minResolution)&&(resolution<=this.maxResolution));}}
+return inRange;},setIsBaseLayer:function(isBaseLayer){if(isBaseLayer!=this.isBaseLayer){this.isBaseLayer=isBaseLayer;if(this.map!=null){this.map.events.triggerEvent("changebaselayer",{layer:this});}}},initResolutions:function(){var i,len;var props={},alwaysInRange=true;for(i=0,len=this.RESOLUTION_PROPERTIES.length;i<len;i++){var p=this.RESOLUTION_PROPERTIES[i];props[p]=this.options[p];if(alwaysInRange&&this.options[p]){alwaysInRange=false;}}
+if(this.alwaysInRange==null){this.alwaysInRange=alwaysInRange;}
+if(props.resolutions==null){props.resolutions=this.resolutionsFromScales(props.scales);}
+if(props.resolutions==null){props.resolutions=this.calculateResolutions(props);}
+if(props.resolutions==null){for(i=0,len=this.RESOLUTION_PROPERTIES.length;i<len;i++){var p=this.RESOLUTION_PROPERTIES[i];props[p]=this.options[p]!=null?this.options[p]:this.map[p];}
+if(props.resolutions==null){props.resolutions=this.resolutionsFromScales(props.scales);}
+if(props.resolutions==null){props.resolutions=this.calculateResolutions(props);}}
+var maxResolution;if(this.options.maxResolution&&this.options.maxResolution!=="auto"){maxResolution=this.options.maxResolution;}
+if(this.options.minScale){maxResolution=OpenLayers.Util.getResolutionFromScale(this.options.minScale,this.units);}
+var minResolution;if(this.options.minResolution&&this.options.minResolution!=="auto"){minResolution=this.options.minResolution;}
+if(this.options.maxScale){minResolution=OpenLayers.Util.getResolutionFromScale(this.options.maxScale,this.units);}
+if(props.resolutions){props.resolutions.sort(function(a,b){return(b-a);});if(!maxResolution){maxResolution=props.resolutions[0];}
+if(!minResolution){var lastIdx=props.resolutions.length-1;minResolution=props.resolutions[lastIdx];}}
+this.resolutions=props.resolutions;if(this.resolutions){len=this.resolutions.length;this.scales=new Array(len);for(i=0;i<len;i++){this.scales[i]=OpenLayers.Util.getScaleFromResolution(this.resolutions[i],this.units);}
+this.numZoomLevels=len;}
+this.minResolution=minResolution;if(minResolution){this.maxScale=OpenLayers.Util.getScaleFromResolution(minResolution,this.units);}
+this.maxResolution=maxResolution;if(maxResolution){this.minScale=OpenLayers.Util.getScaleFromResolution(maxResolution,this.units);}},resolutionsFromScales:function(scales){if(scales==null){return;}
+var resolutions,i,len;len=scales.length;resolutions=new Array(len);for(i=0;i<len;i++){resolutions[i]=OpenLayers.Util.getResolutionFromScale(scales[i],this.units);}
+return resolutions;},calculateResolutions:function(props){var maxResolution=props.maxResolution;if(props.minScale!=null){maxResolution=OpenLayers.Util.getResolutionFromScale(props.minScale,this.units);}else if(maxResolution=="auto"&&this.maxExtent!=null){var viewSize=this.map.getSize();var wRes=this.maxExtent.getWidth()/viewSize.w;var hRes=this.maxExtent.getHeight()/viewSize.h;maxResolution=Math.max(wRes,hRes);}
+var minResolution=props.minResolution;if(props.maxScale!=null){minResolution=OpenLayers.Util.getResolutionFromScale(props.maxScale,this.units);}else if(props.minResolution=="auto"&&this.minExtent!=null){var viewSize=this.map.getSize();var wRes=this.minExtent.getWidth()/viewSize.w;var hRes=this.minExtent.getHeight()/viewSize.h;minResolution=Math.max(wRes,hRes);}
+var maxZoomLevel=props.maxZoomLevel;var numZoomLevels=props.numZoomLevels;if(typeof minResolution==="number"&&typeof maxResolution==="number"&&numZoomLevels===undefined){var ratio=maxResolution/minResolution;numZoomLevels=Math.floor(Math.log(ratio)/Math.log(2))+1;}else if(numZoomLevels===undefined&&maxZoomLevel!=null){numZoomLevels=maxZoomLevel+1;}
+if(typeof numZoomLevels!=="number"||numZoomLevels<=0||(typeof maxResolution!=="number"&&typeof minResolution!=="number")){return;}
+var resolutions=new Array(numZoomLevels);var base=2;if(typeof minResolution=="number"&&typeof maxResolution=="number"){base=Math.pow((maxResolution/minResolution),(1/(numZoomLevels-1)));}
+var i;if(typeof maxResolution==="number"){for(i=0;i<numZoomLevels;i++){resolutions[i]=maxResolution/Math.pow(base,i);}}else{for(i=0;i<numZoomLevels;i++){resolutions[numZoomLevels-1-i]=minResolution*Math.pow(base,i);}}
+return resolutions;},getResolution:function(){var zoom=this.map.getZoom();return this.getResolutionForZoom(zoom);},getExtent:function(){return this.map.calculateBounds();},getZoomForExtent:function(extent,closest){var viewSize=this.map.getSize();var idealResolution=Math.max(extent.getWidth()/viewSize.w,extent.getHeight()/viewSize.h);return this.getZoomForResolution(idealResolution,closest);},getDataExtent:function(){},getResolutionForZoom:function(zoom){zoom=Math.max(0,Math.min(zoom,this.resolutions.length-1));var resolution;if(this.map.fractionalZoom){var low=Math.floor(zoom);var high=Math.ceil(zoom);resolution=this.resolutions[low]-
+((zoom-low)*(this.resolutions[low]-this.resolutions[high]));}else{resolution=this.resolutions[Math.round(zoom)];}
+return resolution;},getZoomForResolution:function(resolution,closest){var zoom;if(this.map.fractionalZoom){var lowZoom=0;var highZoom=this.resolutions.length-1;var highRes=this.resolutions[lowZoom];var lowRes=this.resolutions[highZoom];var res;for(var i=0,len=this.resolutions.length;i<len;++i){res=this.resolutions[i];if(res>=resolution){highRes=res;lowZoom=i;}
+if(res<=resolution){lowRes=res;highZoom=i;break;}}
+var dRes=highRes-lowRes;if(dRes>0){zoom=lowZoom+((highRes-resolution)/dRes);}else{zoom=lowZoom;}}else{var diff;var minDiff=Number.POSITIVE_INFINITY;for(var i=0,len=this.resolutions.length;i<len;i++){if(closest){diff=Math.abs(this.resolutions[i]-resolution);if(diff>minDiff){break;}
+minDiff=diff;}else{if(this.resolutions[i]<resolution){break;}}}
+zoom=Math.max(0,i-1);}
+return zoom;},getLonLatFromViewPortPx:function(viewPortPx){var lonlat=null;if(viewPortPx!=null){var size=this.map.getSize();var center=this.map.getCenter();if(center){var res=this.map.getResolution();var delta_x=viewPortPx.x-(size.w/2);var delta_y=viewPortPx.y-(size.h/2);lonlat=new OpenLayers.LonLat(center.lon+delta_x*res,center.lat-delta_y*res);if(this.wrapDateLine){lonlat=lonlat.wrapDateLine(this.maxExtent);}}}
+return lonlat;},getViewPortPxFromLonLat:function(lonlat){var px=null;if(lonlat!=null){var resolution=this.map.getResolution();var extent=this.map.getExtent();px=new OpenLayers.Pixel((1/resolution*(lonlat.lon-extent.left)),(1/resolution*(extent.top-lonlat.lat)));}
+return px;},setOpacity:function(opacity){if(opacity!=this.opacity){this.opacity=opacity;for(var i=0,len=this.div.childNodes.length;i<len;++i){var element=this.div.childNodes[i].firstChild;OpenLayers.Util.modifyDOMElement(element,null,null,null,null,null,null,opacity);}
+if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"opacity"});}}},getZIndex:function(){return this.div.style.zIndex;},setZIndex:function(zIndex){this.div.style.zIndex=zIndex;},adjustBounds:function(bounds){if(this.gutter){var mapGutter=this.gutter*this.map.getResolution();bounds=new OpenLayers.Bounds(bounds.left-mapGutter,bounds.bottom-mapGutter,bounds.right+mapGutter,bounds.top+mapGutter);}
+if(this.wrapDateLine){var wrappingOptions={'rightTolerance':this.getResolution()};bounds=bounds.wrapDateLine(this.maxExtent,wrappingOptions);}
+return bounds;},CLASS_NAME:"OpenLayers.Layer"});OpenLayers.Marker.Box=OpenLayers.Class(OpenLayers.Marker,{bounds:null,div:null,initialize:function(bounds,borderColor,borderWidth){this.bounds=bounds;this.div=OpenLayers.Util.createDiv();this.div.style.overflow='hidden';this.events=new OpenLayers.Events(this,this.div,null);this.setBorder(borderColor,borderWidth);},destroy:function(){this.bounds=null;this.div=null;OpenLayers.Marker.prototype.destroy.apply(this,arguments);},setBorder:function(color,width){if(!color){color="red";}
+if(!width){width=2;}
+this.div.style.border=width+"px solid "+color;},draw:function(px,sz){OpenLayers.Util.modifyDOMElement(this.div,null,px,sz);return this.div;},onScreen:function(){var onScreen=false;if(this.map){var screenBounds=this.map.getExtent();onScreen=screenBounds.containsBounds(this.bounds,true,true);}
+return onScreen;},display:function(display){this.div.style.display=(display)?"":"none";},CLASS_NAME:"OpenLayers.Marker.Box"});(function(){var oXMLHttpRequest=window.XMLHttpRequest;var bGecko=!!window.controllers,bIE=window.document.all&&!window.opera,bIE7=bIE&&window.navigator.userAgent.match(/MSIE ([\.0-9]+)/)&&RegExp.$1==7;function cXMLHttpRequest(){this._object=oXMLHttpRequest&&!bIE7?new oXMLHttpRequest:new window.ActiveXObject("Microsoft.XMLHTTP");this._listeners=[];};if(bGecko&&oXMLHttpRequest.wrapped)
+cXMLHttpRequest.wrapped=oXMLHttpRequest.wrapped;cXMLHttpRequest.UNSENT=0;cXMLHttpRequest.OPENED=1;cXMLHttpRequest.HEADERS_RECEIVED=2;cXMLHttpRequest.LOADING=3;cXMLHttpRequest.DONE=4;cXMLHttpRequest.prototype.readyState=cXMLHttpRequest.UNSENT;cXMLHttpRequest.prototype.responseText='';cXMLHttpRequest.prototype.responseXML=null;cXMLHttpRequest.prototype.status=0;cXMLHttpRequest.prototype.statusText='';cXMLHttpRequest.prototype.onreadystatechange=null;cXMLHttpRequest.onreadystatechange=null;cXMLHttpRequest.onopen=null;cXMLHttpRequest.onsend=null;cXMLHttpRequest.onabort=null;cXMLHttpRequest.prototype.open=function(sMethod,sUrl,bAsync,sUser,sPassword){delete this._headers;if(arguments.length<3)
+bAsync=true;this._async=bAsync;var oRequest=this,nState=this.readyState,fOnUnload;if(bIE&&bAsync){fOnUnload=function(){if(nState!=cXMLHttpRequest.DONE){fCleanTransport(oRequest);oRequest.abort();}};window.attachEvent("onunload",fOnUnload);}
+if(cXMLHttpRequest.onopen)
+cXMLHttpRequest.onopen.apply(this,arguments);if(arguments.length>4)
+this._object.open(sMethod,sUrl,bAsync,sUser,sPassword);else
+if(arguments.length>3)
+this._object.open(sMethod,sUrl,bAsync,sUser);else
+this._object.open(sMethod,sUrl,bAsync);if(!bGecko&&!bIE){this.readyState=cXMLHttpRequest.OPENED;fReadyStateChange(this);}
+this._object.onreadystatechange=function(){if(bGecko&&!bAsync)
+return;oRequest.readyState=oRequest._object.readyState;fSynchronizeValues(oRequest);if(oRequest._aborted){oRequest.readyState=cXMLHttpRequest.UNSENT;return;}
+if(oRequest.readyState==cXMLHttpRequest.DONE){fCleanTransport(oRequest);if(bIE&&bAsync)
+window.detachEvent("onunload",fOnUnload);}
+if(nState!=oRequest.readyState)
+fReadyStateChange(oRequest);nState=oRequest.readyState;}};cXMLHttpRequest.prototype.send=function(vData){if(cXMLHttpRequest.onsend)
+cXMLHttpRequest.onsend.apply(this,arguments);if(vData&&vData.nodeType){vData=window.XMLSerializer?new window.XMLSerializer().serializeToString(vData):vData.xml;if(!this._headers["Content-Type"])
+this._object.setRequestHeader("Content-Type","application/xml");}
+this._object.send(vData);if(bGecko&&!this._async){this.readyState=cXMLHttpRequest.OPENED;fSynchronizeValues(this);while(this.readyState<cXMLHttpRequest.DONE){this.readyState++;fReadyStateChange(this);if(this._aborted)
+return;}}};cXMLHttpRequest.prototype.abort=function(){if(cXMLHttpRequest.onabort)
+cXMLHttpRequest.onabort.apply(this,arguments);if(this.readyState>cXMLHttpRequest.UNSENT)
+this._aborted=true;this._object.abort();fCleanTransport(this);};cXMLHttpRequest.prototype.getAllResponseHeaders=function(){return this._object.getAllResponseHeaders();};cXMLHttpRequest.prototype.getResponseHeader=function(sName){return this._object.getResponseHeader(sName);};cXMLHttpRequest.prototype.setRequestHeader=function(sName,sValue){if(!this._headers)
+this._headers={};this._headers[sName]=sValue;return this._object.setRequestHeader(sName,sValue);};cXMLHttpRequest.prototype.addEventListener=function(sName,fHandler,bUseCapture){for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++)
+if(oListener[0]==sName&&oListener[1]==fHandler&&oListener[2]==bUseCapture)
+return;this._listeners.push([sName,fHandler,bUseCapture]);};cXMLHttpRequest.prototype.removeEventListener=function(sName,fHandler,bUseCapture){for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++)
+if(oListener[0]==sName&&oListener[1]==fHandler&&oListener[2]==bUseCapture)
+break;if(oListener)
+this._listeners.splice(nIndex,1);};cXMLHttpRequest.prototype.dispatchEvent=function(oEvent){var oEventPseudo={'type':oEvent.type,'target':this,'currentTarget':this,'eventPhase':2,'bubbles':oEvent.bubbles,'cancelable':oEvent.cancelable,'timeStamp':oEvent.timeStamp,'stopPropagation':function(){},'preventDefault':function(){},'initEvent':function(){}};if(oEventPseudo.type=="readystatechange"&&this.onreadystatechange)
+(this.onreadystatechange.handleEvent||this.onreadystatechange).apply(this,[oEventPseudo]);for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++)
+if(oListener[0]==oEventPseudo.type&&!oListener[2])
+(oListener[1].handleEvent||oListener[1]).apply(this,[oEventPseudo]);};cXMLHttpRequest.prototype.toString=function(){return'['+"object"+' '+"XMLHttpRequest"+']';};cXMLHttpRequest.toString=function(){return'['+"XMLHttpRequest"+']';};function fReadyStateChange(oRequest){if(cXMLHttpRequest.onreadystatechange)
+cXMLHttpRequest.onreadystatechange.apply(oRequest);oRequest.dispatchEvent({'type':"readystatechange",'bubbles':false,'cancelable':false,'timeStamp':new Date+0});};function fGetDocument(oRequest){var oDocument=oRequest.responseXML,sResponse=oRequest.responseText;if(bIE&&sResponse&&oDocument&&!oDocument.documentElement&&oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)){oDocument=new window.ActiveXObject("Microsoft.XMLDOM");oDocument.async=false;oDocument.validateOnParse=false;oDocument.loadXML(sResponse);}
+if(oDocument)
+if((bIE&&oDocument.parseError!=0)||!oDocument.documentElement||(oDocument.documentElement&&oDocument.documentElement.tagName=="parsererror"))
+return null;return oDocument;};function fSynchronizeValues(oRequest){try{oRequest.responseText=oRequest._object.responseText;}catch(e){}
+try{oRequest.responseXML=fGetDocument(oRequest._object);}catch(e){}
+try{oRequest.status=oRequest._object.status;}catch(e){}
+try{oRequest.statusText=oRequest._object.statusText;}catch(e){}};function fCleanTransport(oRequest){oRequest._object.onreadystatechange=new window.Function;};if(!window.Function.prototype.apply){window.Function.prototype.apply=function(oRequest,oArguments){if(!oArguments)
+oArguments=[];oRequest.__func=this;oRequest.__func(oArguments[0],oArguments[1],oArguments[2],oArguments[3],oArguments[4]);delete oRequest.__func;};};OpenLayers.Request.XMLHttpRequest=cXMLHttpRequest;})();OpenLayers.Tile.Image.IFrame=OpenLayers.Class(OpenLayers.Tile.Image,{initialize:function(layer,position,bounds,url,size){OpenLayers.Tile.Image.prototype.initialize.apply(this,arguments);this.layerAlphaHack=false;},destroy:function(){if(this.imgDiv!=null){OpenLayers.Event.stopObservingElement(this.imgDiv.firstChild);}
+OpenLayers.Tile.Image.prototype.destroy.apply(this,arguments);},clear:function(){if(this.imgDiv){var iFrame=this.imgDiv.firstChild;OpenLayers.Event.stopObservingElement(iFrame);this.imgDiv.removeChild(iFrame);}},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile.Image.IFrame(this.layer,this.position,this.bounds,this.url,this.size);}
+obj=OpenLayers.Tile.Image.prototype.clone.apply(this,[obj]);return obj;},renderTile:function(){if(OpenLayers.Tile.Image.prototype.renderTile.apply(this,arguments)){var form=this.createRequestForm();this.imgDiv.appendChild(form);form.submit();this.imgDiv.removeChild(form);}},initImgDiv:function(){this.imgDiv=this.createImgDiv();OpenLayers.Util.modifyDOMElement(this.imgDiv,this.id,null,this.layer.getImageSize(),"relative");this.imgDiv.className='olTileImage';this.frame.appendChild(this.imgDiv);this.layer.div.appendChild(this.frame);if(this.layer.opacity!=null){OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,null,null,null,null,this.layer.opacity);}
+this.imgDiv.map=this.layer.map;},createImgDiv:function(){var eventPane=document.createElement("div");if(OpenLayers.Util.getBrowserName()=="msie"){eventPane.style.backgroundColor='#FFFFFF';eventPane.style.filter='chroma(color=#FFFFFF)';}
+OpenLayers.Util.modifyDOMElement(eventPane,null,new OpenLayers.Pixel(0,0),this.layer.getImageSize(),"absolute");var imgDiv=document.createElement("div");imgDiv.appendChild(eventPane);return imgDiv;},createIFrame:function(){var id=this.id+'_iFrame';var iframe;if(OpenLayers.Util.getBrowserName()=="msie"){iframe=document.createElement('<iframe name="'+id+'">');iframe.style.backgroundColor='#FFFFFF';iframe.style.filter='chroma(color=#FFFFFF)';}
+else{iframe=document.createElement('iframe');iframe.style.backgroundColor='transparent';iframe.name=id;}
+iframe.id=id;iframe.scrolling='no';iframe.marginWidth='0px';iframe.marginHeight='0px';iframe.frameBorder='0';OpenLayers.Util.modifyDOMElement(iframe,id,new OpenLayers.Pixel(0,0),this.layer.getImageSize(),"absolute");var onload=function(){this.show();if(this.isLoading){this.isLoading=false;this.events.triggerEvent("loadend");}};OpenLayers.Event.observe(iframe,'load',OpenLayers.Function.bind(onload,this));return iframe;},createRequestForm:function(){var form=document.createElement('form');form.method='POST';var cacheId=this.layer.params["_OLSALT"];cacheId=(cacheId?cacheId+"_":"")+this.bounds.toBBOX();form.action=OpenLayers.Util.urlAppend(this.layer.url,cacheId);this.imgDiv.insertBefore(this.createIFrame(),this.imgDiv.firstChild);form.target=this.id+'_iFrame';var imageSize=this.layer.getImageSize();var params=OpenLayers.Util.extend({"BBOX":this.encodeBBOX?this.bounds.toBBOX():this.bounds.toArray(),"WIDTH":imageSize.w,"HEIGHT":imageSize.h},this.layer.params);for(var par in params){var field=document.createElement('input');field.type='hidden';field.name=par;field.value=params[par];form.appendChild(field);}
+return form;},CLASS_NAME:"OpenLayers.Tile.Image.IFrame"});OpenLayers.ProxyHost="";OpenLayers.nullHandler=function(request){OpenLayers.Console.userError(OpenLayers.i18n("unhandledRequest",{'statusText':request.statusText}));};OpenLayers.loadURL=function(uri,params,caller,onComplete,onFailure){if(typeof params=='string'){params=OpenLayers.Util.getParameters(params);}
+var success=(onComplete)?onComplete:OpenLayers.nullHandler;var failure=(onFailure)?onFailure:OpenLayers.nullHandler;return OpenLayers.Request.GET({url:uri,params:params,success:success,failure:failure,scope:caller});};OpenLayers.parseXMLString=function(text){var index=text.indexOf('<');if(index>0){text=text.substring(index);}
+var ajaxResponse=OpenLayers.Util.Try(function(){var xmldom=new ActiveXObject('Microsoft.XMLDOM');xmldom.loadXML(text);return xmldom;},function(){return new DOMParser().parseFromString(text,'text/xml');},function(){var req=new XMLHttpRequest();req.open("GET","data:"+"text/xml"+";charset=utf-8,"+encodeURIComponent(text),false);if(req.overrideMimeType){req.overrideMimeType("text/xml");}
+req.send(null);return req.responseXML;});return ajaxResponse;};OpenLayers.Ajax={emptyFunction:function(){},getTransport:function(){return OpenLayers.Util.Try(function(){return new XMLHttpRequest();},function(){return new ActiveXObject('Msxml2.XMLHTTP');},function(){return new ActiveXObject('Microsoft.XMLHTTP');})||false;},activeRequestCount:0};OpenLayers.Ajax.Responders={responders:[],register:function(responderToAdd){for(var i=0;i<this.responders.length;i++){if(responderToAdd==this.responders[i]){return;}}
+this.responders.push(responderToAdd);},unregister:function(responderToRemove){OpenLayers.Util.removeItem(this.reponders,responderToRemove);},dispatch:function(callback,request,transport){var responder;for(var i=0;i<this.responders.length;i++){responder=this.responders[i];if(responder[callback]&&typeof responder[callback]=='function'){try{responder[callback].apply(responder,[request,transport]);}catch(e){}}}}};OpenLayers.Ajax.Responders.register({onCreate:function(){OpenLayers.Ajax.activeRequestCount++;},onComplete:function(){OpenLayers.Ajax.activeRequestCount--;}});OpenLayers.Ajax.Base=OpenLayers.Class({initialize:function(options){this.options={method:'post',asynchronous:true,contentType:'application/xml',parameters:''};OpenLayers.Util.extend(this.options,options||{});this.options.method=this.options.method.toLowerCase();if(typeof this.options.parameters=='string'){this.options.parameters=OpenLayers.Util.getParameters(this.options.parameters);}}});OpenLayers.Ajax.Request=OpenLayers.Class(OpenLayers.Ajax.Base,{_complete:false,initialize:function(url,options){OpenLayers.Ajax.Base.prototype.initialize.apply(this,[options]);if(OpenLayers.ProxyHost&&OpenLayers.String.startsWith(url,"http")){url=OpenLayers.ProxyHost+encodeURIComponent(url);}
+this.transport=OpenLayers.Ajax.getTransport();this.request(url);},request:function(url){this.url=url;this.method=this.options.method;var params=OpenLayers.Util.extend({},this.options.parameters);if(this.method!='get'&&this.method!='post'){params['_method']=this.method;this.method='post';}
+this.parameters=params;if(params=OpenLayers.Util.getParameterString(params)){if(this.method=='get'){this.url+=((this.url.indexOf('?')>-1)?'&':'?')+params;}else if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)){params+='&_=';}}
+try{var response=new OpenLayers.Ajax.Response(this);if(this.options.onCreate){this.options.onCreate(response);}
+OpenLayers.Ajax.Responders.dispatch('onCreate',this,response);this.transport.open(this.method.toUpperCase(),this.url,this.options.asynchronous);if(this.options.asynchronous){window.setTimeout(OpenLayers.Function.bind(this.respondToReadyState,this,1),10);}
+this.transport.onreadystatechange=OpenLayers.Function.bind(this.onStateChange,this);this.setRequestHeaders();this.body=this.method=='post'?(this.options.postBody||params):null;this.transport.send(this.body);if(!this.options.asynchronous&&this.transport.overrideMimeType){this.onStateChange();}}catch(e){this.dispatchException(e);}},onStateChange:function(){var readyState=this.transport.readyState;if(readyState>1&&!((readyState==4)&&this._complete)){this.respondToReadyState(this.transport.readyState);}},setRequestHeaders:function(){var headers={'X-Requested-With':'XMLHttpRequest','Accept':'text/javascript, text/html, application/xml, text/xml, */*','OpenLayers':true};if(this.method=='post'){headers['Content-type']=this.options.contentType+
+(this.options.encoding?'; charset='+this.options.encoding:'');if(this.transport.overrideMimeType&&(navigator.userAgent.match(/Gecko\/(\d{4})/)||[0,2005])[1]<2005){headers['Connection']='close';}}
+if(typeof this.options.requestHeaders=='object'){var extras=this.options.requestHeaders;if(typeof extras.push=='function'){for(var i=0,length=extras.length;i<length;i+=2){headers[extras[i]]=extras[i+1];}}else{for(var i in extras){headers[i]=extras[i];}}}
+for(var name in headers){this.transport.setRequestHeader(name,headers[name]);}},success:function(){var status=this.getStatus();return!status||(status>=200&&status<300);},getStatus:function(){try{return this.transport.status||0;}catch(e){return 0;}},respondToReadyState:function(readyState){var state=OpenLayers.Ajax.Request.Events[readyState];var response=new OpenLayers.Ajax.Response(this);if(state=='Complete'){try{this._complete=true;(this.options['on'+response.status]||this.options['on'+(this.success()?'Success':'Failure')]||OpenLayers.Ajax.emptyFunction)(response);}catch(e){this.dispatchException(e);}
+var contentType=response.getHeader('Content-type');}
+try{(this.options['on'+state]||OpenLayers.Ajax.emptyFunction)(response);OpenLayers.Ajax.Responders.dispatch('on'+state,this,response);}catch(e){this.dispatchException(e);}
+if(state=='Complete'){this.transport.onreadystatechange=OpenLayers.Ajax.emptyFunction;}},getHeader:function(name){try{return this.transport.getResponseHeader(name);}catch(e){return null;}},dispatchException:function(exception){var handler=this.options.onException;if(handler){handler(this,exception);OpenLayers.Ajax.Responders.dispatch('onException',this,exception);}else{var listener=false;var responders=OpenLayers.Ajax.Responders.responders;for(var i=0;i<responders.length;i++){if(responders[i].onException){listener=true;break;}}
+if(listener){OpenLayers.Ajax.Responders.dispatch('onException',this,exception);}else{throw exception;}}}});OpenLayers.Ajax.Request.Events=['Uninitialized','Loading','Loaded','Interactive','Complete'];OpenLayers.Ajax.Response=OpenLayers.Class({status:0,statusText:'',initialize:function(request){this.request=request;var transport=this.transport=request.transport,readyState=this.readyState=transport.readyState;if((readyState>2&&!(!!(window.attachEvent&&!window.opera)))||readyState==4){this.status=this.getStatus();this.statusText=this.getStatusText();this.responseText=transport.responseText==null?'':String(transport.responseText);}
+if(readyState==4){var xml=transport.responseXML;this.responseXML=xml===undefined?null:xml;}},getStatus:OpenLayers.Ajax.Request.prototype.getStatus,getStatusText:function(){try{return this.transport.statusText||'';}catch(e){return'';}},getHeader:OpenLayers.Ajax.Request.prototype.getHeader,getResponseHeader:function(name){return this.transport.getResponseHeader(name);}});OpenLayers.Ajax.getElementsByTagNameNS=function(parentnode,nsuri,nsprefix,tagname){var elem=null;if(parentnode.getElementsByTagNameNS){elem=parentnode.getElementsByTagNameNS(nsuri,tagname);}else{elem=parentnode.getElementsByTagName(nsprefix+':'+tagname);}
+return elem;};OpenLayers.Ajax.serializeXMLToString=function(xmldom){var serializer=new XMLSerializer();var data=serializer.serializeToString(xmldom);return data;};OpenLayers.Control.DragFeature=OpenLayers.Class(OpenLayers.Control,{geometryTypes:null,onStart:function(feature,pixel){},onDrag:function(feature,pixel){},onComplete:function(feature,pixel){},documentDrag:false,layer:null,feature:null,dragCallbacks:{},featureCallbacks:{},lastPixel:null,initialize:function(layer,options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.layer=layer;this.handlers={drag:new OpenLayers.Handler.Drag(this,OpenLayers.Util.extend({down:this.downFeature,move:this.moveFeature,up:this.upFeature,out:this.cancel,done:this.doneDragging},this.dragCallbacks),{documentDrag:this.documentDrag}),feature:new OpenLayers.Handler.Feature(this,this.layer,OpenLayers.Util.extend({over:this.overFeature,out:this.outFeature},this.featureCallbacks),{geometryTypes:this.geometryTypes})};},destroy:function(){this.layer=null;OpenLayers.Control.prototype.destroy.apply(this,[]);},activate:function(){return(this.handlers.feature.activate()&&OpenLayers.Control.prototype.activate.apply(this,arguments));},deactivate:function(){this.handlers.drag.deactivate();this.handlers.feature.deactivate();this.feature=null;this.dragging=false;this.lastPixel=null;OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass+"Over");return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},overFeature:function(feature){if(!this.handlers.drag.dragging){this.feature=feature;this.handlers.drag.activate();this.over=true;OpenLayers.Element.addClass(this.map.viewPortDiv,this.displayClass+"Over");}else{if(this.feature.id==feature.id){this.over=true;}else{this.over=false;}}},downFeature:function(pixel){this.lastPixel=pixel;this.onStart(this.feature,pixel);},moveFeature:function(pixel){var res=this.map.getResolution();this.feature.geometry.move(res*(pixel.x-this.lastPixel.x),res*(this.lastPixel.y-pixel.y));this.layer.drawFeature(this.feature);this.lastPixel=pixel;this.onDrag(this.feature,pixel);},upFeature:function(pixel){if(!this.over){this.handlers.drag.deactivate();}},doneDragging:function(pixel){this.onComplete(this.feature,pixel);},outFeature:function(feature){if(!this.handlers.drag.dragging){this.over=false;this.handlers.drag.deactivate();OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass+"Over");this.feature=null;}else{if(this.feature.id==feature.id){this.over=false;}}},cancel:function(){this.handlers.drag.deactivate();this.over=false;},setMap:function(map){this.handlers.drag.setMap(map);this.handlers.feature.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.DragFeature"});OpenLayers.Control.DragPan=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOOL,panned:false,interval:25,documentDrag:false,draw:function(){this.handler=new OpenLayers.Handler.Drag(this,{"move":this.panMap,"done":this.panMapDone},{interval:this.interval,documentDrag:this.documentDrag});},panMap:function(xy){this.panned=true;this.map.pan(this.handler.last.x-xy.x,this.handler.last.y-xy.y,{dragging:this.handler.dragging,animate:false});},panMapDone:function(xy){if(this.panned){this.panMap(xy);this.panned=false;}},CLASS_NAME:"OpenLayers.Control.DragPan"});OpenLayers.Control.KeyboardDefaults=OpenLayers.Class(OpenLayers.Control,{autoActivate:true,slideFactor:75,initialize:function(){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){if(this.handler){this.handler.destroy();}
+this.handler=null;OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){this.handler=new OpenLayers.Handler.Keyboard(this,{"keydown":this.defaultKeyPress});},defaultKeyPress:function(evt){switch(evt.keyCode){case OpenLayers.Event.KEY_LEFT:this.map.pan(-this.slideFactor,0);break;case OpenLayers.Event.KEY_RIGHT:this.map.pan(this.slideFactor,0);break;case OpenLayers.Event.KEY_UP:this.map.pan(0,-this.slideFactor);break;case OpenLayers.Event.KEY_DOWN:this.map.pan(0,this.slideFactor);break;case 33:var size=this.map.getSize();this.map.pan(0,-0.75*size.h);break;case 34:var size=this.map.getSize();this.map.pan(0,0.75*size.h);break;case 35:var size=this.map.getSize();this.map.pan(0.75*size.w,0);break;case 36:var size=this.map.getSize();this.map.pan(-0.75*size.w,0);break;case 43:case 61:case 187:case 107:this.map.zoomIn();break;case 45:case 109:case 189:case 95:this.map.zoomOut();break;}},CLASS_NAME:"OpenLayers.Control.KeyboardDefaults"});OpenLayers.Control.WMSGetFeatureInfo=OpenLayers.Class(OpenLayers.Control,{hover:false,drillDown:false,maxFeatures:10,clickCallback:"click",layers:null,queryVisible:false,url:null,layerUrls:null,infoFormat:'text/html',vendorParams:{},format:null,formatOptions:null,handlerOptions:null,handler:null,hoverRequest:null,EVENT_TYPES:["beforegetfeatureinfo","nogetfeatureinfo","getfeatureinfo"],initialize:function(options){this.EVENT_TYPES=OpenLayers.Control.WMSGetFeatureInfo.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);options=options||{};options.handlerOptions=options.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[options]);if(!this.format){this.format=new OpenLayers.Format.WMSGetFeatureInfo(options.formatOptions);}
+if(this.drillDown===true){this.hover=false;}
+if(this.hover){this.handler=new OpenLayers.Handler.Hover(this,{'move':this.cancelHover,'pause':this.getInfoForHover},OpenLayers.Util.extend(this.handlerOptions.hover||{},{'delay':250}));}else{var callbacks={};callbacks[this.clickCallback]=this.getInfoForClick;this.handler=new OpenLayers.Handler.Click(this,callbacks,this.handlerOptions.click||{});}},activate:function(){if(!this.active){this.handler.activate();}
+return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},getInfoForClick:function(evt){this.events.triggerEvent("beforegetfeatureinfo",{xy:evt.xy});OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait");this.request(evt.xy,{});},getInfoForHover:function(evt){this.events.triggerEvent("beforegetfeatureinfo",{xy:evt.xy});this.request(evt.xy,{hover:true});},cancelHover:function(){if(this.hoverRequest){this.hoverRequest.abort();this.hoverRequest=null;}},findLayers:function(){var candidates=this.layers||this.map.layers;var layers=[];var layer,url;for(var i=0,len=candidates.length;i<len;++i){layer=candidates[i];if(layer instanceof OpenLayers.Layer.WMS&&(!this.queryVisible||layer.getVisibility())){url=layer.url instanceof Array?layer.url[0]:layer.url;if(this.drillDown===false&&!this.url){this.url=url;}
+if(this.drillDown===true||this.urlMatches(url)){layers.push(layer);}}}
+return layers;},urlMatches:function(url){var matches=OpenLayers.Util.isEquivalentUrl(this.url,url);if(!matches&&this.layerUrls){for(var i=0,len=this.layerUrls.length;i<len;++i){if(OpenLayers.Util.isEquivalentUrl(this.layerUrls[i],url)){matches=true;break;}}}
+return matches;},buildWMSOptions:function(url,layers,clickPosition,format){var layerNames=[],styleNames=[];for(var i=0,len=layers.length;i<len;i++){layerNames=layerNames.concat(layers[i].params.LAYERS);styleNames=styleNames.concat(this.getStyleNames(layers[i]));}
+var params=OpenLayers.Util.extend({service:"WMS",version:layers[0].params.VERSION,request:"GetFeatureInfo",layers:layerNames,query_layers:layerNames,styles:styleNames,bbox:this.map.getExtent().toBBOX(null,layers[0].reverseAxisOrder()),feature_count:this.maxFeatures,height:this.map.getSize().h,width:this.map.getSize().w,format:format,info_format:this.infoFormat},(parseFloat(layers[0].params.VERSION)>=1.3)?{crs:this.map.getProjection(),i:clickPosition.x,j:clickPosition.y}:{srs:this.map.getProjection(),x:clickPosition.x,y:clickPosition.y});OpenLayers.Util.applyDefaults(params,this.vendorParams);return{url:url,params:OpenLayers.Util.upperCaseObject(params),callback:function(request){this.handleResponse(clickPosition,request);},scope:this};},getStyleNames:function(layer){var styleNames;if(layer.params.STYLES){styleNames=layer.params.STYLES;}else{if(layer.params.LAYERS instanceof Array){styleNames=new Array(layer.params.LAYERS.length);}else{styleNames=layer.params.LAYERS.replace(/[^,]/g,"");}}
+return styleNames;},request:function(clickPosition,options){var layers=this.findLayers();if(layers.length==0){this.events.triggerEvent("nogetfeatureinfo");OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");return;}
+options=options||{};if(this.drillDown===false){var wmsOptions=this.buildWMSOptions(this.url,layers,clickPosition,layers[0].params.FORMAT);var request=OpenLayers.Request.GET(wmsOptions);if(options.hover===true){this.hoverRequest=request;}}else{this._requestCount=0;this._numRequests=0;this.features=[];var services={},url;for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];var service,found=false;url=layer.url instanceof Array?layer.url[0]:layer.url;if(url in services){services[url].push(layer);}else{this._numRequests++;services[url]=[layer];}}
+var layers;for(var url in services){layers=services[url];var wmsOptions=this.buildWMSOptions(url,layers,clickPosition,layers[0].params.FORMAT);OpenLayers.Request.GET(wmsOptions);}}},triggerGetFeatureInfo:function(request,xy,features){this.events.triggerEvent("getfeatureinfo",{text:request.responseText,features:features,request:request,xy:xy});OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");},handleResponse:function(xy,request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
+var features=this.format.read(doc);if(this.drillDown===false){this.triggerGetFeatureInfo(request,xy,features);}else{this._requestCount++;this._features=(this._features||[]).concat(features);if(this._requestCount===this._numRequests){this.triggerGetFeatureInfo(request,xy,this._features.concat());delete this._features;delete this._requestCount;delete this._numRequests;}}},CLASS_NAME:"OpenLayers.Control.WMSGetFeatureInfo"});OpenLayers.Control.WMTSGetFeatureInfo=OpenLayers.Class(OpenLayers.Control,{hover:false,requestEncoding:"KVP",drillDown:false,maxFeatures:10,clickCallback:"click",layers:null,queryVisible:true,infoFormat:'text/html',vendorParams:{},format:null,formatOptions:null,handlerOptions:null,handler:null,hoverRequest:null,EVENT_TYPES:["beforegetfeatureinfo","getfeatureinfo","exception"],pending:0,initialize:function(options){this.EVENT_TYPES=OpenLayers.Control.WMTSGetFeatureInfo.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);options=options||{};options.handlerOptions=options.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[options]);if(!this.format){this.format=new OpenLayers.Format.WMSGetFeatureInfo(options.formatOptions);}
+if(this.drillDown===true){this.hover=false;}
+if(this.hover){this.handler=new OpenLayers.Handler.Hover(this,{move:this.cancelHover,pause:this.getInfoForHover},OpenLayers.Util.extend(this.handlerOptions.hover||{},{delay:250}));}else{var callbacks={};callbacks[this.clickCallback]=this.getInfoForClick;this.handler=new OpenLayers.Handler.Click(this,callbacks,this.handlerOptions.click||{});}},activate:function(){if(!this.active){this.handler.activate();}
+return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},getInfoForClick:function(evt){this.request(evt.xy,{});},getInfoForHover:function(evt){this.request(evt.xy,{hover:true});},cancelHover:function(){if(this.hoverRequest){--this.pending;if(this.pending<=0){OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");this.pending=0;}
+this.hoverRequest.abort();this.hoverRequest=null;}},findLayers:function(){var candidates=this.layers||this.map.layers;var layers=[];var layer;for(var i=candidates.length-1;i>=0;--i){layer=candidates[i];if(layer instanceof OpenLayers.Layer.WMTS&&layer.requestEncoding===this.requestEncoding&&(!this.queryVisible||layer.getVisibility())){layers.push(layer);if(!this.drillDown||this.hover){break;}}}
+return layers;},buildRequestOptions:function(layer,xy){var loc=this.map.getLonLatFromPixel(xy);var getTileUrl=layer.getURL(new OpenLayers.Bounds(loc.lon,loc.lat,loc.lon,loc.lat));var params=OpenLayers.Util.getParameters(getTileUrl);var tileInfo=layer.getTileInfo(loc);OpenLayers.Util.extend(params,{service:"WMTS",version:layer.version,request:"GetFeatureInfo",infoFormat:this.infoFormat,i:tileInfo.i,j:tileInfo.j});OpenLayers.Util.applyDefaults(params,this.vendorParams);return{url:layer.url instanceof Array?layer.url[0]:layer.url,params:OpenLayers.Util.upperCaseObject(params),callback:function(request){this.handleResponse(xy,request,layer);},scope:this};},request:function(xy,options){options=options||{};var layers=this.findLayers();if(layers.length>0){var issue,layer;for(var i=0,len=layers.length;i<len;i++){layer=layers[i];issue=this.events.triggerEvent("beforegetfeatureinfo",{xy:xy,layer:layer});if(issue!==false){++this.pending;var requestOptions=this.buildRequestOptions(layer,xy);var request=OpenLayers.Request.GET(requestOptions);if(options.hover===true){this.hoverRequest=request;}}}
+if(this.pending>0){OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait");}}},handleResponse:function(xy,request,layer){--this.pending;if(this.pending<=0){OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");this.pending=0;}
+if(request.status&&(request.status<200||request.status>=300)){this.events.triggerEvent("exception",{xy:xy,request:request,layer:layer});}else{var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
+var features,except;try{features=this.format.read(doc);}catch(error){except=true;this.events.triggerEvent("exception",{xy:xy,request:request,error:error,layer:layer});}
+if(!except){this.events.triggerEvent("getfeatureinfo",{text:request.responseText,features:features,request:request,xy:xy,layer:layer});}}},setMap:function(map){this.handler.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.WMTSGetFeatureInfo"});OpenLayers.State={UNKNOWN:'Unknown',INSERT:'Insert',UPDATE:'Update',DELETE:'Delete'};OpenLayers.Feature.Vector=OpenLayers.Class(OpenLayers.Feature,{fid:null,geometry:null,attributes:null,bounds:null,state:null,style:null,url:null,renderIntent:"default",initialize:function(geometry,attributes,style){OpenLayers.Feature.prototype.initialize.apply(this,[null,null,attributes]);this.lonlat=null;this.geometry=geometry?geometry:null;this.state=null;this.attributes={};if(attributes){this.attributes=OpenLayers.Util.extend(this.attributes,attributes);}
+this.style=style?style:null;},destroy:function(){if(this.layer){this.layer.removeFeatures(this);this.layer=null;}
+this.geometry=null;OpenLayers.Feature.prototype.destroy.apply(this,arguments);},clone:function(){return new OpenLayers.Feature.Vector(this.geometry?this.geometry.clone():null,this.attributes,this.style);},onScreen:function(boundsOnly){var onScreen=false;if(this.layer&&this.layer.map){var screenBounds=this.layer.map.getExtent();if(boundsOnly){var featureBounds=this.geometry.getBounds();onScreen=screenBounds.intersectsBounds(featureBounds);}else{var screenPoly=screenBounds.toGeometry();onScreen=screenPoly.intersects(this.geometry);}}
+return onScreen;},getVisibility:function(){return!(this.style&&this.style.display=='none'||!this.layer||this.layer&&this.layer.styleMap&&this.layer.styleMap.createSymbolizer(this,this.renderIntent).display=='none'||this.layer&&!this.layer.getVisibility());},createMarker:function(){return null;},destroyMarker:function(){},createPopup:function(){return null;},atPoint:function(lonlat,toleranceLon,toleranceLat){var atPoint=false;if(this.geometry){atPoint=this.geometry.atPoint(lonlat,toleranceLon,toleranceLat);}
+return atPoint;},destroyPopup:function(){},move:function(location){if(!this.layer||!this.geometry.move){return;}
+var pixel;if(location.CLASS_NAME=="OpenLayers.LonLat"){pixel=this.layer.getViewPortPxFromLonLat(location);}else{pixel=location;}
+var lastPixel=this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());var res=this.layer.map.getResolution();this.geometry.move(res*(pixel.x-lastPixel.x),res*(lastPixel.y-pixel.y));this.layer.drawFeature(this);return lastPixel;},toState:function(state){if(state==OpenLayers.State.UPDATE){switch(this.state){case OpenLayers.State.UNKNOWN:case OpenLayers.State.DELETE:this.state=state;break;case OpenLayers.State.UPDATE:case OpenLayers.State.INSERT:break;}}else if(state==OpenLayers.State.INSERT){switch(this.state){case OpenLayers.State.UNKNOWN:break;default:this.state=state;break;}}else if(state==OpenLayers.State.DELETE){switch(this.state){case OpenLayers.State.INSERT:break;case OpenLayers.State.DELETE:break;case OpenLayers.State.UNKNOWN:case OpenLayers.State.UPDATE:this.state=state;break;}}else if(state==OpenLayers.State.UNKNOWN){this.state=state;}},CLASS_NAME:"OpenLayers.Feature.Vector"});OpenLayers.Feature.Vector.style={'default':{fillColor:"#ee9900",fillOpacity:0.4,hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"#ee9900",strokeOpacity:1,strokeWidth:1,strokeLinecap:"round",strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"inherit"},'select':{fillColor:"blue",fillOpacity:0.4,hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"blue",strokeOpacity:1,strokeWidth:2,strokeLinecap:"round",strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"pointer"},'temporary':{fillColor:"#66cccc",fillOpacity:0.2,hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"#66cccc",strokeOpacity:1,strokeLinecap:"round",strokeWidth:2,strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"inherit"},'delete':{display:"none"}};OpenLayers.Feature.WFS=OpenLayers.Class(OpenLayers.Feature,{initialize:function(layer,xmlNode){var newArguments=arguments;var data=this.processXMLNode(xmlNode);newArguments=new Array(layer,data.lonlat,data);OpenLayers.Feature.prototype.initialize.apply(this,newArguments);this.createMarker();this.layer.addMarker(this.marker);},destroy:function(){if(this.marker!=null){this.layer.removeMarker(this.marker);}
+OpenLayers.Feature.prototype.destroy.apply(this,arguments);},processXMLNode:function(xmlNode){var point=OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,"http://www.opengis.net/gml","gml","Point");var text=OpenLayers.Util.getXmlNodeValue(OpenLayers.Ajax.getElementsByTagNameNS(point[0],"http://www.opengis.net/gml","gml","coordinates")[0]);var floats=text.split(",");return{lonlat:new OpenLayers.LonLat(parseFloat(floats[0]),parseFloat(floats[1])),id:null};},CLASS_NAME:"OpenLayers.Feature.WFS"});OpenLayers.Format.OWSCommon.v1_0_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1,{namespaces:{ows:"http://www.opengis.net/ows/1.0",xlink:"http://www.w3.org/1999/xlink"},readers:{"ows":OpenLayers.Format.OWSCommon.v1.prototype.readers["ows"]},writers:{"ows":OpenLayers.Format.OWSCommon.v1.prototype.writers["ows"]},CLASS_NAME:"OpenLayers.Format.OWSCommon.v1_1_0"});OpenLayers.Format.OWSCommon.v1_1_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1,{namespaces:{ows:"http://www.opengis.net/ows/1.1",xlink:"http://www.w3.org/1999/xlink"},readers:{"ows":OpenLayers.Util.applyDefaults({"AllowedValues":function(node,parameter){parameter.allowedValues={};this.readChildNodes(node,parameter.allowedValues);},"AnyValue":function(node,parameter){parameter.anyValue=true;},"Range":function(node,allowedValues){allowedValues.range={};this.readChildNodes(node,allowedValues.range);},"MinimumValue":function(node,range){range.minValue=this.getChildValue(node);},"MaximumValue":function(node,range){range.maxValue=this.getChildValue(node);},"Identifier":function(node,obj){obj.identifier=this.getChildValue(node);},"SupportedCRS":function(node,obj){obj.supportedCRS=this.getChildValue(node);}},OpenLayers.Format.OWSCommon.v1.prototype.readers["ows"])},CLASS_NAME:"OpenLayers.Format.OWSCommon.v1_1_0"});OpenLayers.Format.OWSContext=OpenLayers.Class(OpenLayers.Format.Context,{defaultVersion:"0.3.1",getParser:function(version){var v=version||this.version||this.defaultVersion;if(v==="0.3.0"){v=this.defaultVersion;}
+if(!this.parser||this.parser.VERSION!=v){var format=OpenLayers.Format.OWSContext["v"+v.replace(/\./g,"_")];if(!format){throw"Can't find a OWSContext parser for version "+v;}
+this.parser=new format(this.options);}
+return this.parser;},toContext:function(obj){var context={};if(obj.CLASS_NAME=="OpenLayers.Map"){context.bounds=obj.getExtent();context.maxExtent=obj.maxExtent;context.projection=obj.projection;context.size=obj.getSize();context.layers=obj.layers;}
+return context;},CLASS_NAME:"OpenLayers.Format.OWSContext"});OpenLayers.Format.WFSCapabilities.v1=OpenLayers.Class(OpenLayers.Format.WFSCapabilities,{initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var capabilities={};var root=data.documentElement;this.runChildNodes(capabilities,root);return capabilities;},runChildNodes:function(obj,node){var children=node.childNodes;var childNode,processor;for(var i=0;i<children.length;++i){childNode=children[i];if(childNode.nodeType==1){processor=this["read_cap_"+childNode.nodeName];if(processor){processor.apply(this,[obj,childNode]);}}}},read_cap_FeatureTypeList:function(request,node){var featureTypeList={featureTypes:[]};this.runChildNodes(featureTypeList,node);request.featureTypeList=featureTypeList;},read_cap_FeatureType:function(featureTypeList,node,parentLayer){var featureType={};this.runChildNodes(featureType,node);featureTypeList.featureTypes.push(featureType);},read_cap_Name:function(obj,node){var name=this.getChildValue(node);if(name){var parts=name.split(":");obj.name=parts.pop();if(parts.length>0){obj.featureNS=this.lookupNamespaceURI(node,parts[0]);}}},read_cap_Title:function(obj,node){var title=this.getChildValue(node);if(title){obj.title=title;}},read_cap_Abstract:function(obj,node){var abst=this.getChildValue(node);if(abst){obj["abstract"]=abst;}},CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1"});OpenLayers.Format.WMC=OpenLayers.Class(OpenLayers.Format.Context,{defaultVersion:"1.1.0",getParser:function(version){var v=version||this.version||this.defaultVersion;if(!this.parser||this.parser.VERSION!=v){var format=OpenLayers.Format.WMC["v"+v.replace(/\./g,"_")];if(!format){throw"Can't find a WMC parser for version "+v;}
+this.parser=new format(this.options);}
+return this.parser;},layerToContext:function(layer){var parser=this.getParser();var layerContext={queryable:layer.queryable,visibility:layer.visibility,name:layer.params["LAYERS"],title:layer.name,metadataURL:layer.metadataURL,version:layer.params["VERSION"],url:layer.url,maxExtent:layer.maxExtent,transparent:layer.params["TRANSPARENT"],numZoomLevels:layer.numZoomLevels,units:layer.units,isBaseLayer:layer.isBaseLayer,opacity:layer.opacity,displayInLayerSwitcher:layer.displayInLayerSwitcher,singleTile:layer.singleTile,tileSize:(layer.singleTile||!layer.tileSize)?undefined:{width:layer.tileSize.w,height:layer.tileSize.h},minScale:(layer.options.resolutions||layer.options.scales||layer.options.maxResolution||layer.options.minScale)?layer.minScale:undefined,maxScale:(layer.options.resolutions||layer.options.scales||layer.options.minResolution||layer.options.maxScale)?layer.maxScale:undefined,formats:[{value:layer.params["FORMAT"],current:true}],styles:[{href:layer.params["SLD"],body:layer.params["SLD_BODY"],name:layer.params["STYLES"]||parser.defaultStyleName,title:parser.defaultStyleTitle,current:true}]};return layerContext;},toContext:function(obj){var context={};var layers=obj.layers;if(obj.CLASS_NAME=="OpenLayers.Map"){context.bounds=obj.getExtent();context.maxExtent=obj.maxExtent;context.projection=obj.projection;context.size=obj.getSize();}
+else{OpenLayers.Util.applyDefaults(context,obj);if(context.layers!=undefined){delete(context.layers);}}
+if(context.layersContext==undefined){context.layersContext=[];}
+if(layers!=undefined&&layers instanceof Array){for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];if(layer instanceof OpenLayers.Layer.WMS){context.layersContext.push(this.layerToContext(layer));}}}
+return context;},CLASS_NAME:"OpenLayers.Format.WMC"});OpenLayers.Format.WMSCapabilities.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{wms:"http://www.opengis.net/wms",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"wms",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+if(data&&data.nodeType==9){data=data.documentElement;}
+var capabilities={};this.readNode(data,capabilities);this.postProcessLayers(capabilities);return capabilities;},postProcessLayers:function(capabilities){if(capabilities.capability){capabilities.capability.layers=[];var layers=capabilities.capability.nestedLayers;for(var i=0,len=layers.length;i<len;++i){var layer=layers[i];this.processLayer(capabilities.capability,layer);}}},processLayer:function(capability,layer,parentLayer){if(layer.formats===undefined){layer.formats=capability.request.getmap.formats;}
+if(parentLayer){layer.styles=layer.styles.concat(parentLayer.styles);var attributes=["queryable","cascaded","fixedWidth","fixedHeight","opaque","noSubsets","llbbox","minScale","maxScale","attribution"];var complexAttr=["srs","bbox","dimensions","authorityURLs"];var key;for(var j=0;j<attributes.length;j++){key=attributes[j];if(key in parentLayer){if(layer[key]==null){layer[key]=parentLayer[key];}
+if(layer[key]==null){var intAttr=["cascaded","fixedWidth","fixedHeight"];var boolAttr=["queryable","opaque","noSubsets"];if(OpenLayers.Util.indexOf(intAttr,key)!=-1){layer[key]=0;}
+if(OpenLayers.Util.indexOf(boolAttr,key)!=-1){layer[key]=false;}}}}
+for(var j=0;j<complexAttr.length;j++){key=complexAttr[j];layer[key]=OpenLayers.Util.extend(layer[key],parentLayer[key]);}}
+for(var i=0,len=layer.nestedLayers.length;i<len;i++){var childLayer=layer.nestedLayers[i];this.processLayer(capability,childLayer,layer);}
+if(layer.name){capability.layers.push(layer);}},readers:{"wms":{"Service":function(node,obj){obj.service={};this.readChildNodes(node,obj.service);},"Name":function(node,obj){obj.name=this.getChildValue(node);},"Title":function(node,obj){obj.title=this.getChildValue(node);},"Abstract":function(node,obj){obj["abstract"]=this.getChildValue(node);},"BoundingBox":function(node,obj){var bbox={};bbox.bbox=[parseFloat(node.getAttribute("minx")),parseFloat(node.getAttribute("miny")),parseFloat(node.getAttribute("maxx")),parseFloat(node.getAttribute("maxy"))];var res={x:parseFloat(node.getAttribute("resx")),y:parseFloat(node.getAttribute("resy"))};if(!(isNaN(res.x)&&isNaN(res.y))){bbox.res=res;}
+return bbox;},"OnlineResource":function(node,obj){obj.href=this.getAttributeNS(node,this.namespaces.xlink,"href");},"ContactInformation":function(node,obj){obj.contactInformation={};this.readChildNodes(node,obj.contactInformation);},"ContactPersonPrimary":function(node,obj){obj.personPrimary={};this.readChildNodes(node,obj.personPrimary);},"ContactPerson":function(node,obj){obj.person=this.getChildValue(node);},"ContactOrganization":function(node,obj){obj.organization=this.getChildValue(node);},"ContactPosition":function(node,obj){obj.position=this.getChildValue(node);},"ContactAddress":function(node,obj){obj.contactAddress={};this.readChildNodes(node,obj.contactAddress);},"AddressType":function(node,obj){obj.type=this.getChildValue(node);},"Address":function(node,obj){obj.address=this.getChildValue(node);},"City":function(node,obj){obj.city=this.getChildValue(node);},"StateOrProvince":function(node,obj){obj.stateOrProvince=this.getChildValue(node);},"PostCode":function(node,obj){obj.postcode=this.getChildValue(node);},"Country":function(node,obj){obj.country=this.getChildValue(node);},"ContactVoiceTelephone":function(node,obj){obj.phone=this.getChildValue(node);},"ContactFacsimileTelephone":function(node,obj){obj.fax=this.getChildValue(node);},"ContactElectronicMailAddress":function(node,obj){obj.email=this.getChildValue(node);},"Fees":function(node,obj){var fees=this.getChildValue(node);if(fees&&fees.toLowerCase()!="none"){obj.fees=fees;}},"AccessConstraints":function(node,obj){var constraints=this.getChildValue(node);if(constraints&&constraints.toLowerCase()!="none"){obj.accessConstraints=constraints;}},"Capability":function(node,obj){obj.capability={nestedLayers:[]};this.readChildNodes(node,obj.capability);},"Request":function(node,obj){obj.request={};this.readChildNodes(node,obj.request);},"GetCapabilities":function(node,obj){obj.getcapabilities={formats:[]};this.readChildNodes(node,obj.getcapabilities);},"Format":function(node,obj){if(obj.formats instanceof Array){obj.formats.push(this.getChildValue(node));}else{obj.format=this.getChildValue(node);}},"DCPType":function(node,obj){this.readChildNodes(node,obj);},"HTTP":function(node,obj){this.readChildNodes(node,obj);},"Get":function(node,obj){this.readChildNodes(node,obj);},"Post":function(node,obj){this.readChildNodes(node,obj);},"GetMap":function(node,obj){obj.getmap={formats:[]};this.readChildNodes(node,obj.getmap);},"GetFeatureInfo":function(node,obj){obj.getfeatureinfo={formats:[]};this.readChildNodes(node,obj.getfeatureinfo);},"Exception":function(node,obj){obj.exception={formats:[]};this.readChildNodes(node,obj.exception);},"Layer":function(node,obj){var attrNode=node.getAttributeNode("queryable");var queryable=(attrNode&&attrNode.specified)?node.getAttribute("queryable"):null;attrNode=node.getAttributeNode("cascaded");var cascaded=(attrNode&&attrNode.specified)?node.getAttribute("cascaded"):null;attrNode=node.getAttributeNode("opaque");var opaque=(attrNode&&attrNode.specified)?node.getAttribute('opaque'):null;var noSubsets=node.getAttribute('noSubsets');var fixedWidth=node.getAttribute('fixedWidth');var fixedHeight=node.getAttribute('fixedHeight');var layer={nestedLayers:[],styles:[],srs:{},metadataURLs:[],bbox:{},dimensions:{},authorityURLs:{},identifiers:{},keywords:[],queryable:(queryable&&queryable!=="")?(queryable==="1"||queryable==="true"):null,cascaded:(cascaded!==null)?parseInt(cascaded):null,opaque:opaque?(opaque==="1"||opaque==="true"):null,noSubsets:(noSubsets!==null)?(noSubsets==="1"||noSubsets==="true"):null,fixedWidth:(fixedWidth!=null)?parseInt(fixedWidth):null,fixedHeight:(fixedHeight!=null)?parseInt(fixedHeight):null};obj.nestedLayers.push(layer);this.readChildNodes(node,layer);if(layer.name){var parts=layer.name.split(":");if(parts.length>0){layer.prefix=parts[0];}}},"Attribution":function(node,obj){obj.attribution={};this.readChildNodes(node,obj.attribution);},"LogoURL":function(node,obj){obj.logo={width:node.getAttribute("width"),height:node.getAttribute("height")};this.readChildNodes(node,obj.logo);},"Style":function(node,obj){var style={};obj.styles.push(style);this.readChildNodes(node,style);},"LegendURL":function(node,obj){var legend={width:node.getAttribute("width"),height:node.getAttribute("height")};obj.legend=legend;this.readChildNodes(node,legend);},"MetadataURL":function(node,obj){var metadataURL={type:node.getAttribute("type")};obj.metadataURLs.push(metadataURL);this.readChildNodes(node,metadataURL);},"DataURL":function(node,obj){obj.dataURL={};this.readChildNodes(node,obj.dataURL);},"FeatureListURL":function(node,obj){obj.featureListURL={};this.readChildNodes(node,obj.featureListURL);},"AuthorityURL":function(node,obj){var name=node.getAttribute("name");var authority={};this.readChildNodes(node,authority);obj.authorityURLs[name]=authority.href;},"Identifier":function(node,obj){var authority=node.getAttribute("authority");obj.identifiers[authority]=this.getChildValue(node);},"KeywordList":function(node,obj){this.readChildNodes(node,obj);},"SRS":function(node,obj){obj.srs[this.getChildValue(node)]=true;}}},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1"});OpenLayers.Format.WMSDescribeLayer.v1_1=OpenLayers.Class(OpenLayers.Format.WMSDescribeLayer,{initialize:function(options){OpenLayers.Format.WMSDescribeLayer.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var root=data.documentElement;var children=root.childNodes;var describelayer=[];var childNode,nodeName;for(var i=0;i<children.length;++i){childNode=children[i];nodeName=childNode.nodeName;if(nodeName=='LayerDescription'){var layerName=childNode.getAttribute('name');var owsType='';var owsURL='';var typeName='';if(childNode.getAttribute('owsType')){owsType=childNode.getAttribute('owsType');owsURL=childNode.getAttribute('owsURL');}else{if(childNode.getAttribute('wfs')!=''){owsType='WFS';owsURL=childNode.getAttribute('wfs');}else if(childNode.getAttribute('wcs')!=''){owsType='WCS';owsURL=childNode.getAttribute('wcs');}}
+var query=childNode.getElementsByTagName('Query');if(query.length>0){typeName=query[0].getAttribute('typeName');if(!typeName){typeName=query[0].getAttribute('typename');}}
+describelayer.push({layerName:layerName,owsType:owsType,owsURL:owsURL,typeName:typeName});}}
+return describelayer;},CLASS_NAME:"OpenLayers.Format.WMSDescribeLayer.v1_1"});OpenLayers.Handler.Box=OpenLayers.Class(OpenLayers.Handler,{dragHandler:null,boxDivClassName:'olHandlerBoxZoomBox',boxCharacteristics:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);var callbacks={"down":this.startBox,"move":this.moveBox,"out":this.removeBox,"up":this.endBox};this.dragHandler=new OpenLayers.Handler.Drag(this,callbacks,{keyMask:this.keyMask});},destroy:function(){if(this.dragHandler){this.dragHandler.destroy();this.dragHandler=null;}
+OpenLayers.Handler.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Handler.prototype.setMap.apply(this,arguments);if(this.dragHandler){this.dragHandler.setMap(map);}},startBox:function(xy){this.zoomBox=OpenLayers.Util.createDiv('zoomBox',this.dragHandler.start);this.zoomBox.className=this.boxDivClassName;this.zoomBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.viewPortDiv.appendChild(this.zoomBox);OpenLayers.Element.addClass(this.map.viewPortDiv,"olDrawBox");},moveBox:function(xy){var startX=this.dragHandler.start.x;var startY=this.dragHandler.start.y;var deltaX=Math.abs(startX-xy.x);var deltaY=Math.abs(startY-xy.y);this.zoomBox.style.width=Math.max(1,deltaX)+"px";this.zoomBox.style.height=Math.max(1,deltaY)+"px";this.zoomBox.style.left=xy.x<startX?xy.x+"px":startX+"px";this.zoomBox.style.top=xy.y<startY?xy.y+"px":startY+"px";var box=this.getBoxCharacteristics();if(box.newBoxModel){if(xy.x>startX){this.zoomBox.style.width=Math.max(1,deltaX-box.xOffset)+"px";}
+if(xy.y>startY){this.zoomBox.style.height=Math.max(1,deltaY-box.yOffset)+"px";}}},endBox:function(end){var result;if(Math.abs(this.dragHandler.start.x-end.x)>5||Math.abs(this.dragHandler.start.y-end.y)>5){var start=this.dragHandler.start;var top=Math.min(start.y,end.y);var bottom=Math.max(start.y,end.y);var left=Math.min(start.x,end.x);var right=Math.max(start.x,end.x);result=new OpenLayers.Bounds(left,bottom,right,top);}else{result=this.dragHandler.start.clone();}
+this.removeBox();this.callback("done",[result]);},removeBox:function(){this.map.viewPortDiv.removeChild(this.zoomBox);this.zoomBox=null;this.boxCharacteristics=null;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDrawBox");},activate:function(){if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){this.dragHandler.activate();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.dragHandler.deactivate();return true;}else{return false;}},getBoxCharacteristics:function(){if(!this.boxCharacteristics){var xOffset=parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-left-width"))+parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-right-width"))+1;var yOffset=parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-top-width"))+parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-bottom-width"))+1;var newBoxModel=OpenLayers.Util.getBrowserName()=="msie"?document.compatMode!="BackCompat":true;this.boxCharacteristics={xOffset:xOffset,yOffset:yOffset,newBoxModel:newBoxModel};}
+return this.boxCharacteristics;},CLASS_NAME:"OpenLayers.Handler.Box"});OpenLayers.Handler.RegularPolygon=OpenLayers.Class(OpenLayers.Handler.Drag,{sides:4,radius:null,snapAngle:null,snapToggle:'shiftKey',layerOptions:null,persist:false,irregular:false,angle:null,fixedRadius:false,feature:null,layer:null,origin:null,initialize:function(control,callbacks,options){if(!(options&&options.layerOptions&&options.layerOptions.styleMap)){this.style=OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'],{});}
+OpenLayers.Handler.prototype.initialize.apply(this,[control,callbacks,options]);this.options=(options)?options:{};},setOptions:function(newOptions){OpenLayers.Util.extend(this.options,newOptions);OpenLayers.Util.extend(this,newOptions);},activate:function(){var activated=false;if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){var options=OpenLayers.Util.extend({displayInLayerSwitcher:false,calculateInRange:OpenLayers.Function.True},this.layerOptions);this.layer=new OpenLayers.Layer.Vector(this.CLASS_NAME,options);this.map.addLayer(this.layer);activated=true;}
+return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.Drag.prototype.deactivate.apply(this,arguments)){if(this.dragging){this.cancel();}
+if(this.layer.map!=null){this.layer.destroy(false);if(this.feature){this.feature.destroy();}}
+this.layer=null;this.feature=null;deactivated=true;}
+return deactivated;},down:function(evt){this.fixedRadius=!!(this.radius);var maploc=this.map.getLonLatFromPixel(evt.xy);this.origin=new OpenLayers.Geometry.Point(maploc.lon,maploc.lat);if(!this.fixedRadius||this.irregular){this.radius=this.map.getResolution();}
+if(this.persist){this.clear();}
+this.feature=new OpenLayers.Feature.Vector();this.createGeometry();this.callback("create",[this.origin,this.feature]);this.layer.addFeatures([this.feature],{silent:true});this.layer.drawFeature(this.feature,this.style);},move:function(evt){var maploc=this.map.getLonLatFromPixel(evt.xy);var point=new OpenLayers.Geometry.Point(maploc.lon,maploc.lat);if(this.irregular){var ry=Math.sqrt(2)*Math.abs(point.y-this.origin.y)/2;this.radius=Math.max(this.map.getResolution()/2,ry);}else if(this.fixedRadius){this.origin=point;}else{this.calculateAngle(point,evt);this.radius=Math.max(this.map.getResolution()/2,point.distanceTo(this.origin));}
+this.modifyGeometry();if(this.irregular){var dx=point.x-this.origin.x;var dy=point.y-this.origin.y;var ratio;if(dy==0){ratio=dx/(this.radius*Math.sqrt(2));}else{ratio=dx/dy;}
+this.feature.geometry.resize(1,this.origin,ratio);this.feature.geometry.move(dx/2,dy/2);}
+this.layer.drawFeature(this.feature,this.style);},up:function(evt){this.finalize();if(this.start==this.last){this.callback("done",[evt.xy]);}},out:function(evt){this.finalize();},createGeometry:function(){this.angle=Math.PI*((1/this.sides)-(1/2));if(this.snapAngle){this.angle+=this.snapAngle*(Math.PI/180);}
+this.feature.geometry=OpenLayers.Geometry.Polygon.createRegularPolygon(this.origin,this.radius,this.sides,this.snapAngle);},modifyGeometry:function(){var angle,point;var ring=this.feature.geometry.components[0];if(ring.components.length!=(this.sides+1)){this.createGeometry();ring=this.feature.geometry.components[0];}
+for(var i=0;i<this.sides;++i){point=ring.components[i];angle=this.angle+(i*2*Math.PI/this.sides);point.x=this.origin.x+(this.radius*Math.cos(angle));point.y=this.origin.y+(this.radius*Math.sin(angle));point.clearBounds();}},calculateAngle:function(point,evt){var alpha=Math.atan2(point.y-this.origin.y,point.x-this.origin.x);if(this.snapAngle&&(this.snapToggle&&!evt[this.snapToggle])){var snapAngleRad=(Math.PI/180)*this.snapAngle;this.angle=Math.round(alpha/snapAngleRad)*snapAngleRad;}else{this.angle=alpha;}},cancel:function(){this.callback("cancel",null);this.finalize();},finalize:function(){this.origin=null;this.radius=this.options.radius;},clear:function(){if(this.layer){this.layer.renderer.clear();this.layer.destroyFeatures();}},callback:function(name,args){if(this.callbacks[name]){this.callbacks[name].apply(this.control,[this.feature.geometry.clone()]);}
+if(!this.persist&&(name=="done"||name=="cancel")){this.clear();}},CLASS_NAME:"OpenLayers.Handler.RegularPolygon"});OpenLayers.Layer.EventPane=OpenLayers.Class(OpenLayers.Layer,{smoothDragPan:true,isBaseLayer:true,isFixed:true,pane:null,mapObject:null,initialize:function(name,options){OpenLayers.Layer.prototype.initialize.apply(this,arguments);if(this.pane==null){this.pane=OpenLayers.Util.createDiv(this.div.id+"_EventPane");}},destroy:function(){this.mapObject=null;this.pane=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Layer.prototype.setMap.apply(this,arguments);this.pane.style.zIndex=parseInt(this.div.style.zIndex)+1;this.pane.style.display=this.div.style.display;this.pane.style.width="100%";this.pane.style.height="100%";if(OpenLayers.Util.getBrowserName()=="msie"){this.pane.style.background="url("+OpenLayers.Util.getImagesLocation()+"blank.gif)";}
+if(this.isFixed){this.map.viewPortDiv.appendChild(this.pane);}else{this.map.layerContainerDiv.appendChild(this.pane);}
+this.loadMapObject();if(this.mapObject==null){this.loadWarningMessage();}},removeMap:function(map){if(this.pane&&this.pane.parentNode){this.pane.parentNode.removeChild(this.pane);}
+OpenLayers.Layer.prototype.removeMap.apply(this,arguments);},loadWarningMessage:function(){this.div.style.backgroundColor="darkblue";var viewSize=this.map.getSize();var msgW=Math.min(viewSize.w,300);var msgH=Math.min(viewSize.h,200);var size=new OpenLayers.Size(msgW,msgH);var centerPx=new OpenLayers.Pixel(viewSize.w/2,viewSize.h/2);var topLeft=centerPx.add(-size.w/2,-size.h/2);var div=OpenLayers.Util.createDiv(this.name+"_warning",topLeft,size,null,null,null,"auto");div.style.padding="7px";div.style.backgroundColor="yellow";div.innerHTML=this.getWarningHTML();this.div.appendChild(div);},getWarningHTML:function(){return"";},display:function(display){OpenLayers.Layer.prototype.display.apply(this,arguments);this.pane.style.display=this.div.style.display;},setZIndex:function(zIndex){OpenLayers.Layer.prototype.setZIndex.apply(this,arguments);this.pane.style.zIndex=parseInt(this.div.style.zIndex)+1;},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);if(this.mapObject!=null){var newCenter=this.map.getCenter();var newZoom=this.map.getZoom();if(newCenter!=null){var moOldCenter=this.getMapObjectCenter();var oldCenter=this.getOLLonLatFromMapObjectLonLat(moOldCenter);var moOldZoom=this.getMapObjectZoom();var oldZoom=this.getOLZoomFromMapObjectZoom(moOldZoom);if(!(newCenter.equals(oldCenter))||!(newZoom==oldZoom)){if(dragging&&this.dragPanMapObject&&this.smoothDragPan){var oldPx=this.map.getViewPortPxFromLonLat(oldCenter);var newPx=this.map.getViewPortPxFromLonLat(newCenter);this.dragPanMapObject(newPx.x-oldPx.x,oldPx.y-newPx.y);}else{var center=this.getMapObjectLonLatFromOLLonLat(newCenter);var zoom=this.getMapObjectZoomFromOLZoom(newZoom);this.setMapObjectCenter(center,zoom,dragging);}}}}},getLonLatFromViewPortPx:function(viewPortPx){var lonlat=null;if((this.mapObject!=null)&&(this.getMapObjectCenter()!=null)){var moPixel=this.getMapObjectPixelFromOLPixel(viewPortPx);var moLonLat=this.getMapObjectLonLatFromMapObjectPixel(moPixel);lonlat=this.getOLLonLatFromMapObjectLonLat(moLonLat);}
+return lonlat;},getViewPortPxFromLonLat:function(lonlat){var viewPortPx=null;if((this.mapObject!=null)&&(this.getMapObjectCenter()!=null)){var moLonLat=this.getMapObjectLonLatFromOLLonLat(lonlat);var moPixel=this.getMapObjectPixelFromMapObjectLonLat(moLonLat);viewPortPx=this.getOLPixelFromMapObjectPixel(moPixel);}
+return viewPortPx;},getOLLonLatFromMapObjectLonLat:function(moLonLat){var olLonLat=null;if(moLonLat!=null){var lon=this.getLongitudeFromMapObjectLonLat(moLonLat);var lat=this.getLatitudeFromMapObjectLonLat(moLonLat);olLonLat=new OpenLayers.LonLat(lon,lat);}
+return olLonLat;},getMapObjectLonLatFromOLLonLat:function(olLonLat){var moLatLng=null;if(olLonLat!=null){moLatLng=this.getMapObjectLonLatFromLonLat(olLonLat.lon,olLonLat.lat);}
+return moLatLng;},getOLPixelFromMapObjectPixel:function(moPixel){var olPixel=null;if(moPixel!=null){var x=this.getXFromMapObjectPixel(moPixel);var y=this.getYFromMapObjectPixel(moPixel);olPixel=new OpenLayers.Pixel(x,y);}
+return olPixel;},getMapObjectPixelFromOLPixel:function(olPixel){var moPixel=null;if(olPixel!=null){moPixel=this.getMapObjectPixelFromXY(olPixel.x,olPixel.y);}
+return moPixel;},CLASS_NAME:"OpenLayers.Layer.EventPane"});OpenLayers.Layer.FixedZoomLevels=OpenLayers.Class({initialize:function(){},initResolutions:function(){var props=new Array('minZoomLevel','maxZoomLevel','numZoomLevels');for(var i=0,len=props.length;i<len;i++){var property=props[i];this[property]=(this.options[property]!=null)?this.options[property]:this.map[property];}
+if((this.minZoomLevel==null)||(this.minZoomLevel<this.MIN_ZOOM_LEVEL)){this.minZoomLevel=this.MIN_ZOOM_LEVEL;}
+var desiredZoomLevels;var limitZoomLevels=this.MAX_ZOOM_LEVEL-this.minZoomLevel+1;if(((this.options.numZoomLevels==null)&&(this.options.maxZoomLevel!=null))||((this.numZoomLevels==null)&&(this.maxZoomLevel!=null))){desiredZoomLevels=this.maxZoomLevel-this.minZoomLevel+1;}else{desiredZoomLevels=this.numZoomLevels;}
+if(desiredZoomLevels!=null){this.numZoomLevels=Math.min(desiredZoomLevels,limitZoomLevels);}else{this.numZoomLevels=limitZoomLevels;}
+this.maxZoomLevel=this.minZoomLevel+this.numZoomLevels-1;if(this.RESOLUTIONS!=null){var resolutionsIndex=0;this.resolutions=[];for(var i=this.minZoomLevel;i<=this.maxZoomLevel;i++){this.resolutions[resolutionsIndex++]=this.RESOLUTIONS[i];}
+this.maxResolution=this.resolutions[0];this.minResolution=this.resolutions[this.resolutions.length-1];}},getResolution:function(){if(this.resolutions!=null){return OpenLayers.Layer.prototype.getResolution.apply(this,arguments);}else{var resolution=null;var viewSize=this.map.getSize();var extent=this.getExtent();if((viewSize!=null)&&(extent!=null)){resolution=Math.max(extent.getWidth()/viewSize.w,extent.getHeight()/viewSize.h);}
+return resolution;}},getExtent:function(){var extent=null;var size=this.map.getSize();var tlPx=new OpenLayers.Pixel(0,0);var tlLL=this.getLonLatFromViewPortPx(tlPx);var brPx=new OpenLayers.Pixel(size.w,size.h);var brLL=this.getLonLatFromViewPortPx(brPx);if((tlLL!=null)&&(brLL!=null)){extent=new OpenLayers.Bounds(tlLL.lon,brLL.lat,brLL.lon,tlLL.lat);}
+return extent;},getZoomForResolution:function(resolution){if(this.resolutions!=null){return OpenLayers.Layer.prototype.getZoomForResolution.apply(this,arguments);}else{var extent=OpenLayers.Layer.prototype.getExtent.apply(this,[]);return this.getZoomForExtent(extent);}},getOLZoomFromMapObjectZoom:function(moZoom){var zoom=null;if(moZoom!=null){zoom=moZoom-this.minZoomLevel;}
+return zoom;},getMapObjectZoomFromOLZoom:function(olZoom){var zoom=null;if(olZoom!=null){zoom=olZoom+this.minZoomLevel;}
+return zoom;},CLASS_NAME:"OpenLayers.Layer.FixedZoomLevels"});OpenLayers.Layer.HTTPRequest=OpenLayers.Class(OpenLayers.Layer,{URL_HASH_FACTOR:(Math.sqrt(5)-1)/2,url:null,params:null,reproject:false,initialize:function(name,url,params,options){var newArguments=arguments;newArguments=[name,options];OpenLayers.Layer.prototype.initialize.apply(this,newArguments);this.url=url;this.params=OpenLayers.Util.extend({},params);},destroy:function(){this.url=null;this.params=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.HTTPRequest(this.name,this.url,this.params,this.getOptions());}
+obj=OpenLayers.Layer.prototype.clone.apply(this,[obj]);return obj;},setUrl:function(newUrl){this.url=newUrl;},mergeNewParams:function(newParams){this.params=OpenLayers.Util.extend(this.params,newParams);var ret=this.redraw();if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"params"});}
+return ret;},redraw:function(force){if(force){return this.mergeNewParams({"_olSalt":Math.random()});}else{return OpenLayers.Layer.prototype.redraw.apply(this,[]);}},selectUrl:function(paramString,urls){var product=1;for(var i=0,len=paramString.length;i<len;i++){product*=paramString.charCodeAt(i)*this.URL_HASH_FACTOR;product-=Math.floor(product);}
+return urls[Math.floor(product*urls.length)];},getFullRequestString:function(newParams,altUrl){var url=altUrl||this.url;var allParams=OpenLayers.Util.extend({},this.params);allParams=OpenLayers.Util.extend(allParams,newParams);var paramsString=OpenLayers.Util.getParameterString(allParams);if(url instanceof Array){url=this.selectUrl(paramsString,url);}
+var urlParams=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));for(var key in allParams){if(key.toUpperCase()in urlParams){delete allParams[key];}}
+paramsString=OpenLayers.Util.getParameterString(allParams);return OpenLayers.Util.urlAppend(url,paramsString);},CLASS_NAME:"OpenLayers.Layer.HTTPRequest"});OpenLayers.Layer.Image=OpenLayers.Class(OpenLayers.Layer,{isBaseLayer:true,url:null,extent:null,size:null,tile:null,aspectRatio:null,initialize:function(name,url,extent,size,options){this.url=url;this.extent=extent;this.maxExtent=extent;this.size=size;OpenLayers.Layer.prototype.initialize.apply(this,[name,options]);this.aspectRatio=(this.extent.getHeight()/this.size.h)/(this.extent.getWidth()/this.size.w);},destroy:function(){if(this.tile){this.removeTileMonitoringHooks(this.tile);this.tile.destroy();this.tile=null;}
+OpenLayers.Layer.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Image(this.name,this.url,this.extent,this.size,this.getOptions());}
+obj=OpenLayers.Layer.prototype.clone.apply(this,[obj]);return obj;},setMap:function(map){if(this.options.maxResolution==null){this.options.maxResolution=this.aspectRatio*this.extent.getWidth()/this.size.w;}
+OpenLayers.Layer.prototype.setMap.apply(this,arguments);},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);var firstRendering=(this.tile==null);if(zoomChanged||firstRendering){this.setTileSize();var ul=new OpenLayers.LonLat(this.extent.left,this.extent.top);var ulPx=this.map.getLayerPxFromLonLat(ul);if(firstRendering){this.tile=new OpenLayers.Tile.Image(this,ulPx,this.extent,null,this.tileSize);this.addTileMonitoringHooks(this.tile);}else{this.tile.size=this.tileSize.clone();this.tile.position=ulPx.clone();}
+this.tile.draw();}},setTileSize:function(){var tileWidth=this.extent.getWidth()/this.map.getResolution();var tileHeight=this.extent.getHeight()/this.map.getResolution();this.tileSize=new OpenLayers.Size(tileWidth,tileHeight);},addTileMonitoringHooks:function(tile){tile.onLoadStart=function(){this.events.triggerEvent("loadstart");};tile.events.register("loadstart",this,tile.onLoadStart);tile.onLoadEnd=function(){this.events.triggerEvent("loadend");};tile.events.register("loadend",this,tile.onLoadEnd);tile.events.register("unload",this,tile.onLoadEnd);},removeTileMonitoringHooks:function(tile){tile.unload();tile.events.un({"loadstart":tile.onLoadStart,"loadend":tile.onLoadEnd,"unload":tile.onLoadEnd,scope:this});},setUrl:function(newUrl){this.url=newUrl;this.tile.draw();},getURL:function(bounds){return this.url;},CLASS_NAME:"OpenLayers.Layer.Image"});OpenLayers.Layer.Markers=OpenLayers.Class(OpenLayers.Layer,{isBaseLayer:false,markers:null,drawn:false,initialize:function(name,options){OpenLayers.Layer.prototype.initialize.apply(this,arguments);this.markers=[];},destroy:function(){this.clearMarkers();this.markers=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},setOpacity:function(opacity){if(opacity!=this.opacity){this.opacity=opacity;for(var i=0,len=this.markers.length;i<len;i++){this.markers[i].setOpacity(this.opacity);}}},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);if(zoomChanged||!this.drawn){for(var i=0,len=this.markers.length;i<len;i++){this.drawMarker(this.markers[i]);}
+this.drawn=true;}},addMarker:function(marker){this.markers.push(marker);if(this.opacity!=null){marker.setOpacity(this.opacity);}
+if(this.map&&this.map.getExtent()){marker.map=this.map;this.drawMarker(marker);}},removeMarker:function(marker){if(this.markers&&this.markers.length){OpenLayers.Util.removeItem(this.markers,marker);marker.erase();}},clearMarkers:function(){if(this.markers!=null){while(this.markers.length>0){this.removeMarker(this.markers[0]);}}},drawMarker:function(marker){var px=this.map.getLayerPxFromLonLat(marker.lonlat);if(px==null){marker.display(false);}else{if(!marker.isDrawn()){var markerImg=marker.draw(px);this.div.appendChild(markerImg);}else if(marker.icon){marker.icon.moveTo(px);}}},getDataExtent:function(){var maxExtent=null;if(this.markers&&(this.markers.length>0)){var maxExtent=new OpenLayers.Bounds();for(var i=0,len=this.markers.length;i<len;i++){var marker=this.markers[i];maxExtent.extend(marker.lonlat);}}
+return maxExtent;},CLASS_NAME:"OpenLayers.Layer.Markers"});OpenLayers.Layer.SphericalMercator={getExtent:function(){var extent=null;if(this.sphericalMercator){extent=this.map.calculateBounds();}else{extent=OpenLayers.Layer.FixedZoomLevels.prototype.getExtent.apply(this);}
+return extent;},getLonLatFromViewPortPx:function(viewPortPx){return OpenLayers.Layer.prototype.getLonLatFromViewPortPx.apply(this,arguments);},getViewPortPxFromLonLat:function(lonlat){return OpenLayers.Layer.prototype.getViewPortPxFromLonLat.apply(this,arguments);},initMercatorParameters:function(){this.RESOLUTIONS=[];var maxResolution=156543.0339;for(var zoom=0;zoom<=this.MAX_ZOOM_LEVEL;++zoom){this.RESOLUTIONS[zoom]=maxResolution/Math.pow(2,zoom);}
+this.units="m";this.projection=this.projection||"EPSG:900913";},forwardMercator:function(lon,lat){var x=lon*20037508.34/180;var y=Math.log(Math.tan((90+lat)*Math.PI/360))/(Math.PI/180);y=y*20037508.34/180;return new OpenLayers.LonLat(x,y);},inverseMercator:function(x,y){var lon=(x/20037508.34)*180;var lat=(y/20037508.34)*180;lat=180/Math.PI*(2*Math.atan(Math.exp(lat*Math.PI/180))-Math.PI/2);return new OpenLayers.LonLat(lon,lat);},projectForward:function(point){var lonlat=OpenLayers.Layer.SphericalMercator.forwardMercator(point.x,point.y);point.x=lonlat.lon;point.y=lonlat.lat;return point;},projectInverse:function(point){var lonlat=OpenLayers.Layer.SphericalMercator.inverseMercator(point.x,point.y);point.x=lonlat.lon;point.y=lonlat.lat;return point;}};OpenLayers.Projection.addTransform("EPSG:4326","EPSG:900913",OpenLayers.Layer.SphericalMercator.projectForward);OpenLayers.Projection.addTransform("EPSG:900913","EPSG:4326",OpenLayers.Layer.SphericalMercator.projectInverse);OpenLayers.Tile.WFS=OpenLayers.Class(OpenLayers.Tile,{features:null,url:null,request:null,initialize:function(layer,position,bounds,url,size){OpenLayers.Tile.prototype.initialize.apply(this,arguments);this.url=url;this.features=[];},destroy:function(){OpenLayers.Tile.prototype.destroy.apply(this,arguments);this.destroyAllFeatures();this.features=null;this.url=null;if(this.request){this.request.abort();this.request=null;}},clear:function(){this.destroyAllFeatures();},draw:function(){if(OpenLayers.Tile.prototype.draw.apply(this,arguments)){if(this.isLoading){this.events.triggerEvent("reload");}else{this.isLoading=true;this.events.triggerEvent("loadstart");}
+this.loadFeaturesForRegion(this.requestSuccess);}},loadFeaturesForRegion:function(success,failure){if(this.request){this.request.abort();}
+this.request=OpenLayers.Request.GET({url:this.url,success:success,failure:failure,scope:this});},requestSuccess:function(request){if(this.features){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
+if(this.layer.vectorMode){this.layer.addFeatures(this.layer.formatObject.read(doc));}else{var xml=new OpenLayers.Format.XML();if(typeof doc=="string"){doc=xml.read(doc);}
+var resultFeatures=xml.getElementsByTagNameNS(doc,"http://www.opengis.net/gml","featureMember");this.addResults(resultFeatures);}}
+if(this.events){this.events.triggerEvent("loadend");}
+this.request=null;},addResults:function(results){for(var i=0;i<results.length;i++){var feature=new this.layer.featureClass(this.layer,results[i]);this.features.push(feature);}},destroyAllFeatures:function(){while(this.features.length>0){var feature=this.features.shift();feature.destroy();}},CLASS_NAME:"OpenLayers.Tile.WFS"});OpenLayers.Control.DrawFeature=OpenLayers.Class(OpenLayers.Control,{layer:null,callbacks:null,EVENT_TYPES:["featureadded"],multi:false,featureAdded:function(){},handlerOptions:null,initialize:function(layer,handler,options){this.EVENT_TYPES=OpenLayers.Control.DrawFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.callbacks=OpenLayers.Util.extend({done:this.drawFeature,modify:function(vertex,feature){this.layer.events.triggerEvent("sketchmodified",{vertex:vertex,feature:feature});},create:function(vertex,feature){this.layer.events.triggerEvent("sketchstarted",{vertex:vertex,feature:feature});}},this.callbacks);this.layer=layer;this.handlerOptions=this.handlerOptions||{};if(!("multi"in this.handlerOptions)){this.handlerOptions.multi=this.multi;}
+var sketchStyle=this.layer.styleMap&&this.layer.styleMap.styles.temporary;if(sketchStyle){this.handlerOptions.layerOptions=OpenLayers.Util.applyDefaults(this.handlerOptions.layerOptions,{styleMap:new OpenLayers.StyleMap({"default":sketchStyle})});}
+this.handler=new handler(this,this.callbacks,this.handlerOptions);},drawFeature:function(geometry){var feature=new OpenLayers.Feature.Vector(geometry);var proceed=this.layer.events.triggerEvent("sketchcomplete",{feature:feature});if(proceed!==false){feature.state=OpenLayers.State.INSERT;this.layer.addFeatures([feature]);this.featureAdded(feature);this.events.triggerEvent("featureadded",{feature:feature});}},CLASS_NAME:"OpenLayers.Control.DrawFeature"});OpenLayers.Control.Measure=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:['measure','measurepartial'],handlerOptions:null,callbacks:null,displaySystem:'metric',geodesic:false,displaySystemUnits:{geographic:['dd'],english:['mi','ft','in'],metric:['km','m']},partialDelay:300,delayedTrigger:null,persist:false,initialize:function(handler,options){this.EVENT_TYPES=OpenLayers.Control.Measure.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.callbacks=OpenLayers.Util.extend({done:this.measureComplete,point:this.measurePartial},this.callbacks);this.handlerOptions=OpenLayers.Util.extend({persist:this.persist},this.handlerOptions);this.handler=new handler(this,this.callbacks,this.handlerOptions);},cancel:function(){this.handler.cancel();},updateHandler:function(handler,options){var active=this.active;if(active){this.deactivate();}
+this.handler=new handler(this,this.callbacks,options);if(active){this.activate();}},measureComplete:function(geometry){if(this.delayedTrigger){window.clearTimeout(this.delayedTrigger);}
+this.measure(geometry,"measure");},measurePartial:function(point,geometry){if(geometry.getLength()>0){geometry=geometry.clone();this.delayedTrigger=window.setTimeout(OpenLayers.Function.bind(function(){this.measure(geometry,"measurepartial");},this),this.partialDelay);}},measure:function(geometry,eventType){var stat,order;if(geometry.CLASS_NAME.indexOf('LineString')>-1){stat=this.getBestLength(geometry);order=1;}else{stat=this.getBestArea(geometry);order=2;}
+this.events.triggerEvent(eventType,{measure:stat[0],units:stat[1],order:order,geometry:geometry});},getBestArea:function(geometry){var units=this.displaySystemUnits[this.displaySystem];var unit,area;for(var i=0,len=units.length;i<len;++i){unit=units[i];area=this.getArea(geometry,unit);if(area>1){break;}}
+return[area,unit];},getArea:function(geometry,units){var area,geomUnits;if(this.geodesic){area=geometry.getGeodesicArea(this.map.getProjectionObject());geomUnits="m";}else{area=geometry.getArea();geomUnits=this.map.getUnits();}
+var inPerDisplayUnit=OpenLayers.INCHES_PER_UNIT[units];if(inPerDisplayUnit){var inPerMapUnit=OpenLayers.INCHES_PER_UNIT[geomUnits];area*=Math.pow((inPerMapUnit/inPerDisplayUnit),2);}
+return area;},getBestLength:function(geometry){var units=this.displaySystemUnits[this.displaySystem];var unit,length;for(var i=0,len=units.length;i<len;++i){unit=units[i];length=this.getLength(geometry,unit);if(length>1){break;}}
+return[length,unit];},getLength:function(geometry,units){var length,geomUnits;if(this.geodesic){length=geometry.getGeodesicLength(this.map.getProjectionObject());geomUnits="m";}else{length=geometry.getLength();geomUnits=this.map.getUnits();}
+var inPerDisplayUnit=OpenLayers.INCHES_PER_UNIT[units];if(inPerDisplayUnit){var inPerMapUnit=OpenLayers.INCHES_PER_UNIT[geomUnits];length*=(inPerMapUnit/inPerDisplayUnit);}
+return length;},CLASS_NAME:"OpenLayers.Control.Measure"});OpenLayers.Control.ZoomBox=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOOL,out:false,alwaysZoom:false,draw:function(){this.handler=new OpenLayers.Handler.Box(this,{done:this.zoomBox},{keyMask:this.keyMask});},zoomBox:function(position){if(position instanceof OpenLayers.Bounds){var bounds;if(!this.out){var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));bounds=new OpenLayers.Bounds(minXY.lon,minXY.lat,maxXY.lon,maxXY.lat);}else{var pixWidth=Math.abs(position.right-position.left);var pixHeight=Math.abs(position.top-position.bottom);var zoomFactor=Math.min((this.map.size.h/pixHeight),(this.map.size.w/pixWidth));var extent=this.map.getExtent();var center=this.map.getLonLatFromPixel(position.getCenterPixel());var xmin=center.lon-(extent.getWidth()/2)*zoomFactor;var xmax=center.lon+(extent.getWidth()/2)*zoomFactor;var ymin=center.lat-(extent.getHeight()/2)*zoomFactor;var ymax=center.lat+(extent.getHeight()/2)*zoomFactor;bounds=new OpenLayers.Bounds(xmin,ymin,xmax,ymax);}
+var lastZoom=this.map.getZoom();this.map.zoomToExtent(bounds);if(lastZoom==this.map.getZoom()&&this.alwaysZoom==true){this.map.zoomTo(lastZoom+(this.out?-1:1));}}else{if(!this.out){this.map.setCenter(this.map.getLonLatFromPixel(position),this.map.getZoom()+1);}else{this.map.setCenter(this.map.getLonLatFromPixel(position),this.map.getZoom()-1);}}},CLASS_NAME:"OpenLayers.Control.ZoomBox"});OpenLayers.Format.WFSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.WFSCapabilities.v1,{initialize:function(options){OpenLayers.Format.WFSCapabilities.v1.prototype.initialize.apply(this,[options]);},read_cap_Service:function(capabilities,node){var service={};this.runChildNodes(service,node);capabilities.service=service;},read_cap_Fees:function(service,node){var fees=this.getChildValue(node);if(fees&&fees.toLowerCase()!="none"){service.fees=fees;}},read_cap_AccessConstraints:function(service,node){var constraints=this.getChildValue(node);if(constraints&&constraints.toLowerCase()!="none"){service.accessConstraints=constraints;}},read_cap_OnlineResource:function(service,node){var onlineResource=this.getChildValue(node);if(onlineResource&&onlineResource.toLowerCase()!="none"){service.onlineResource=onlineResource;}},read_cap_Keywords:function(service,node){var keywords=this.getChildValue(node);if(keywords&&keywords.toLowerCase()!="none"){service.keywords=keywords.split(', ');}},read_cap_Capability:function(capabilities,node){var capability={};this.runChildNodes(capability,node);capabilities.capability=capability;},read_cap_Request:function(obj,node){var request={};this.runChildNodes(request,node);obj.request=request;},read_cap_GetFeature:function(request,node){var getfeature={href:{},formats:[]};this.runChildNodes(getfeature,node);request.getfeature=getfeature;},read_cap_ResultFormat:function(obj,node){var children=node.childNodes;var childNode;for(var i=0;i<children.length;i++){childNode=children[i];if(childNode.nodeType==1){obj.formats.push(childNode.nodeName);}}},read_cap_DCPType:function(obj,node){this.runChildNodes(obj,node);},read_cap_HTTP:function(obj,node){this.runChildNodes(obj.href,node);},read_cap_Get:function(obj,node){obj.get=node.getAttribute("onlineResource");},read_cap_Post:function(obj,node){obj.post=node.getAttribute("onlineResource");},CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1_0_0"});OpenLayers.Format.WFSCapabilities.v1_1_0=OpenLayers.Class(OpenLayers.Format.WFSCapabilities.v1,{initialize:function(options){OpenLayers.Format.WFSCapabilities.v1.prototype.initialize.apply(this,[options]);},CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1_1_0"});OpenLayers.Format.WKT=OpenLayers.Class(OpenLayers.Format,{initialize:function(options){this.regExes={'typeStr':/^\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/,'spaces':/\s+/,'parenComma':/\)\s*,\s*\(/,'doubleParenComma':/\)\s*\)\s*,\s*\(\s*\(/,'trimParens':/^\s*\(?(.*?)\)?\s*$/};OpenLayers.Format.prototype.initialize.apply(this,[options]);},read:function(wkt){var features,type,str;var matches=this.regExes.typeStr.exec(wkt);if(matches){type=matches[1].toLowerCase();str=matches[2];if(this.parse[type]){features=this.parse[type].apply(this,[str]);}
+if(this.internalProjection&&this.externalProjection){if(features&&features.CLASS_NAME=="OpenLayers.Feature.Vector"){features.geometry.transform(this.externalProjection,this.internalProjection);}else if(features&&type!="geometrycollection"&&typeof features=="object"){for(var i=0,len=features.length;i<len;i++){var component=features[i];component.geometry.transform(this.externalProjection,this.internalProjection);}}}}
+return features;},write:function(features){var collection,geometry,type,data,isCollection;if(features.constructor==Array){collection=features;isCollection=true;}else{collection=[features];isCollection=false;}
+var pieces=[];if(isCollection){pieces.push('GEOMETRYCOLLECTION(');}
+for(var i=0,len=collection.length;i<len;++i){if(isCollection&&i>0){pieces.push(',');}
+geometry=collection[i].geometry;type=geometry.CLASS_NAME.split('.')[2].toLowerCase();if(!this.extract[type]){return null;}
+if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
+data=this.extract[type].apply(this,[geometry]);pieces.push(type.toUpperCase()+'('+data+')');}
+if(isCollection){pieces.push(')');}
+return pieces.join('');},extract:{'point':function(point){return point.x+' '+point.y;},'multipoint':function(multipoint){var array=[];for(var i=0,len=multipoint.components.length;i<len;++i){array.push('('+
+this.extract.point.apply(this,[multipoint.components[i]])+')');}
+return array.join(',');},'linestring':function(linestring){var array=[];for(var i=0,len=linestring.components.length;i<len;++i){array.push(this.extract.point.apply(this,[linestring.components[i]]));}
+return array.join(',');},'multilinestring':function(multilinestring){var array=[];for(var i=0,len=multilinestring.components.length;i<len;++i){array.push('('+
+this.extract.linestring.apply(this,[multilinestring.components[i]])+')');}
+return array.join(',');},'polygon':function(polygon){var array=[];for(var i=0,len=polygon.components.length;i<len;++i){array.push('('+
+this.extract.linestring.apply(this,[polygon.components[i]])+')');}
+return array.join(',');},'multipolygon':function(multipolygon){var array=[];for(var i=0,len=multipolygon.components.length;i<len;++i){array.push('('+
+this.extract.polygon.apply(this,[multipolygon.components[i]])+')');}
+return array.join(',');}},parse:{'point':function(str){var coords=OpenLayers.String.trim(str).split(this.regExes.spaces);return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(coords[0],coords[1]));},'multipoint':function(str){var point;var points=OpenLayers.String.trim(str).split(this.regExes.parenComma);var components=[];for(var i=0,len=points.length;i<len;++i){point=points[i].replace(this.regExes.trimParens,'$1');components.push(this.parse.point.apply(this,[point]).geometry);}
+return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPoint(components));},'linestring':function(str){var points=OpenLayers.String.trim(str).split(',');var components=[];for(var i=0,len=points.length;i<len;++i){components.push(this.parse.point.apply(this,[points[i]]).geometry);}
+return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(components));},'multilinestring':function(str){var line;var lines=OpenLayers.String.trim(str).split(this.regExes.parenComma);var components=[];for(var i=0,len=lines.length;i<len;++i){line=lines[i].replace(this.regExes.trimParens,'$1');components.push(this.parse.linestring.apply(this,[line]).geometry);}
+return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiLineString(components));},'polygon':function(str){var ring,linestring,linearring;var rings=OpenLayers.String.trim(str).split(this.regExes.parenComma);var components=[];for(var i=0,len=rings.length;i<len;++i){ring=rings[i].replace(this.regExes.trimParens,'$1');linestring=this.parse.linestring.apply(this,[ring]).geometry;linearring=new OpenLayers.Geometry.LinearRing(linestring.components);components.push(linearring);}
+return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon(components));},'multipolygon':function(str){var polygon;var polygons=OpenLayers.String.trim(str).split(this.regExes.doubleParenComma);var components=[];for(var i=0,len=polygons.length;i<len;++i){polygon=polygons[i].replace(this.regExes.trimParens,'$1');components.push(this.parse.polygon.apply(this,[polygon]).geometry);}
+return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPolygon(components));},'geometrycollection':function(str){str=str.replace(/,\s*([A-Za-z])/g,'|$1');var wktArray=OpenLayers.String.trim(str).split('|');var components=[];for(var i=0,len=wktArray.length;i<len;++i){components.push(OpenLayers.Format.WKT.prototype.read.apply(this,[wktArray[i]]));}
+return components;}},CLASS_NAME:"OpenLayers.Format.WKT"});OpenLayers.Format.WMC.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ol:"http://openlayers.org/context",wmc:"http://www.opengis.net/context",sld:"http://www.opengis.net/sld",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},schemaLocation:"",getNamespacePrefix:function(uri){var prefix=null;if(uri==null){prefix=this.namespaces[this.defaultPrefix];}else{for(prefix in this.namespaces){if(this.namespaces[prefix]==uri){break;}}}
+return prefix;},defaultPrefix:"wmc",rootPrefix:null,defaultStyleName:"",defaultStyleTitle:"Default",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var root=data.documentElement;this.rootPrefix=root.prefix;var context={version:root.getAttribute("version")};this.runChildNodes(context,root);return context;},runChildNodes:function(obj,node){var children=node.childNodes;var childNode,processor,prefix,local;for(var i=0,len=children.length;i<len;++i){childNode=children[i];if(childNode.nodeType==1){prefix=this.getNamespacePrefix(childNode.namespaceURI);local=childNode.nodeName.split(":").pop();processor=this["read_"+prefix+"_"+local];if(processor){processor.apply(this,[obj,childNode]);}}}},read_wmc_General:function(context,node){this.runChildNodes(context,node);},read_wmc_BoundingBox:function(context,node){context.projection=node.getAttribute("SRS");context.bounds=new OpenLayers.Bounds(parseFloat(node.getAttribute("minx")),parseFloat(node.getAttribute("miny")),parseFloat(node.getAttribute("maxx")),parseFloat(node.getAttribute("maxy")));},read_wmc_LayerList:function(context,node){context.layersContext=[];this.runChildNodes(context,node);},read_wmc_Layer:function(context,node){var layerContext={visibility:(node.getAttribute("hidden")!="1"),queryable:(node.getAttribute("queryable")=="1"),formats:[],styles:[]};this.runChildNodes(layerContext,node);context.layersContext.push(layerContext);},read_wmc_Extension:function(obj,node){this.runChildNodes(obj,node);},read_ol_units:function(layerContext,node){layerContext.units=this.getChildValue(node);},read_ol_maxExtent:function(obj,node){var bounds=new OpenLayers.Bounds(node.getAttribute("minx"),node.getAttribute("miny"),node.getAttribute("maxx"),node.getAttribute("maxy"));obj.maxExtent=bounds;},read_ol_transparent:function(layerContext,node){layerContext.transparent=this.getChildValue(node);},read_ol_numZoomLevels:function(layerContext,node){layerContext.numZoomLevels=parseInt(this.getChildValue(node));},read_ol_opacity:function(layerContext,node){layerContext.opacity=parseFloat(this.getChildValue(node));},read_ol_singleTile:function(layerContext,node){layerContext.singleTile=(this.getChildValue(node)=="true");},read_ol_tileSize:function(layerContext,node){var obj={"width":node.getAttribute("width"),"height":node.getAttribute("height")};layerContext.tileSize=obj;},read_ol_isBaseLayer:function(layerContext,node){layerContext.isBaseLayer=(this.getChildValue(node)=="true");},read_ol_displayInLayerSwitcher:function(layerContext,node){layerContext.displayInLayerSwitcher=(this.getChildValue(node)=="true");},read_wmc_Server:function(layerContext,node){layerContext.version=node.getAttribute("version");var server={};var links=node.getElementsByTagName("OnlineResource");if(links.length>0){this.read_wmc_OnlineResource(server,links[0]);}
+layerContext.url=server.href;},read_wmc_FormatList:function(layerContext,node){this.runChildNodes(layerContext,node);},read_wmc_Format:function(layerContext,node){var format={value:this.getChildValue(node)};if(node.getAttribute("current")=="1"){format.current=true;}
+layerContext.formats.push(format);},read_wmc_StyleList:function(layerContext,node){this.runChildNodes(layerContext,node);},read_wmc_Style:function(layerContext,node){var style={};this.runChildNodes(style,node);if(node.getAttribute("current")=="1"){style.current=true;}
+layerContext.styles.push(style);},read_wmc_SLD:function(style,node){this.runChildNodes(style,node);},read_sld_StyledLayerDescriptor:function(sld,node){var xml=OpenLayers.Format.XML.prototype.write.apply(this,[node]);sld.body=xml;},read_wmc_OnlineResource:function(obj,node){obj.href=this.getAttributeNS(node,this.namespaces.xlink,"href");},read_wmc_Name:function(obj,node){var name=this.getChildValue(node);if(name){obj.name=name;}},read_wmc_Title:function(obj,node){var title=this.getChildValue(node);if(title){obj.title=title;}},read_wmc_MetadataURL:function(layerContext,node){var metadataURL={};var links=node.getElementsByTagName("OnlineResource");if(links.length>0){this.read_wmc_OnlineResource(metadataURL,links[0]);}
+layerContext.metadataURL=metadataURL.href;},read_wmc_Abstract:function(obj,node){var abst=this.getChildValue(node);if(abst){obj["abstract"]=abst;}},read_wmc_LegendURL:function(style,node){var legend={width:node.getAttribute('width'),height:node.getAttribute('height')};var links=node.getElementsByTagName("OnlineResource");if(links.length>0){this.read_wmc_OnlineResource(legend,links[0]);}
+style.legend=legend;},write:function(context,options){var root=this.createElementDefaultNS("ViewContext");this.setAttributes(root,{version:this.VERSION,id:(options&&typeof options.id=="string")?options.id:OpenLayers.Util.createUniqueID("OpenLayers_Context_")});this.setAttributeNS(root,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);root.appendChild(this.write_wmc_General(context));root.appendChild(this.write_wmc_LayerList(context));return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},createElementDefaultNS:function(name,childValue,attributes){var node=this.createElementNS(this.namespaces[this.defaultPrefix],name);if(childValue){node.appendChild(this.createTextNode(childValue));}
+if(attributes){this.setAttributes(node,attributes);}
+return node;},setAttributes:function(node,obj){var value;for(var name in obj){value=obj[name].toString();if(value.match(/[A-Z]/)){this.setAttributeNS(node,null,name,value);}else{node.setAttribute(name,value);}}},write_wmc_General:function(context){var node=this.createElementDefaultNS("General");if(context.size){node.appendChild(this.createElementDefaultNS("Window",null,{width:context.size.w,height:context.size.h}));}
+var bounds=context.bounds;node.appendChild(this.createElementDefaultNS("BoundingBox",null,{minx:bounds.left.toPrecision(18),miny:bounds.bottom.toPrecision(18),maxx:bounds.right.toPrecision(18),maxy:bounds.top.toPrecision(18),SRS:context.projection}));node.appendChild(this.createElementDefaultNS("Title",context.title));node.appendChild(this.write_ol_MapExtension(context));return node;},write_ol_MapExtension:function(context){var node=this.createElementDefaultNS("Extension");var bounds=context.maxExtent;if(bounds){var maxExtent=this.createElementNS(this.namespaces.ol,"ol:maxExtent");this.setAttributes(maxExtent,{minx:bounds.left.toPrecision(18),miny:bounds.bottom.toPrecision(18),maxx:bounds.right.toPrecision(18),maxy:bounds.top.toPrecision(18)});node.appendChild(maxExtent);}
+return node;},write_wmc_LayerList:function(context){var list=this.createElementDefaultNS("LayerList");for(var i=0,len=context.layersContext.length;i<len;++i){list.appendChild(this.write_wmc_Layer(context.layersContext[i]));}
+return list;},write_wmc_Layer:function(context){var node=this.createElementDefaultNS("Layer",null,{queryable:context.queryable?"1":"0",hidden:context.visibility?"0":"1"});node.appendChild(this.write_wmc_Server(context));node.appendChild(this.createElementDefaultNS("Name",context.name));node.appendChild(this.createElementDefaultNS("Title",context.title));if(context.metadataURL){node.appendChild(this.write_wmc_MetadataURL(context.metadataURL));}
+return node;},write_wmc_LayerExtension:function(context){var node=this.createElementDefaultNS("Extension");var bounds=context.maxExtent;var maxExtent=this.createElementNS(this.namespaces.ol,"ol:maxExtent");this.setAttributes(maxExtent,{minx:bounds.left.toPrecision(18),miny:bounds.bottom.toPrecision(18),maxx:bounds.right.toPrecision(18),maxy:bounds.top.toPrecision(18)});node.appendChild(maxExtent);if(context.tileSize&&!context.singleTile){var size=this.createElementNS(this.namespaces.ol,"ol:tileSize");this.setAttributes(size,context.tileSize);node.appendChild(size);}
+var properties=["transparent","numZoomLevels","units","isBaseLayer","opacity","displayInLayerSwitcher","singleTile"];var child;for(var i=0,len=properties.length;i<len;++i){child=this.createOLPropertyNode(context,properties[i]);if(child){node.appendChild(child);}}
+return node;},createOLPropertyNode:function(obj,prop){var node=null;if(obj[prop]!=null){node=this.createElementNS(this.namespaces.ol,"ol:"+prop);node.appendChild(this.createTextNode(obj[prop].toString()));}
+return node;},write_wmc_Server:function(context){var node=this.createElementDefaultNS("Server");this.setAttributes(node,{service:"OGC:WMS",version:context.version});node.appendChild(this.write_wmc_OnlineResource(context.url));return node;},write_wmc_MetadataURL:function(metadataURL){var node=this.createElementDefaultNS("MetadataURL");node.appendChild(this.write_wmc_OnlineResource(metadataURL));return node;},write_wmc_FormatList:function(context){var node=this.createElementDefaultNS("FormatList");for(var i=0,len=context.formats.length;i<len;i++){var format=context.formats[i];node.appendChild(this.createElementDefaultNS("Format",format.value,(format.current&&format.current==true)?{current:"1"}:null));}
+return node;},write_wmc_StyleList:function(layer){var node=this.createElementDefaultNS("StyleList");var styles=layer.styles;if(styles&&styles instanceof Array){var sld;for(var i=0,len=styles.length;i<len;i++){var s=styles[i];var style=this.createElementDefaultNS("Style",null,(s.current&&s.current==true)?{current:"1"}:null);if(s.href){sld=this.createElementDefaultNS("SLD");var link=this.write_wmc_OnlineResource(s.href);sld.appendChild(link);sld.appendChild(this.createElementDefaultNS("Name",s.name));if(s.title){sld.appendChild(this.createElementDefaultNS("Title",s.title));}
+style.appendChild(sld);}else if(s.body){sld=this.createElementDefaultNS("SLD");var doc=OpenLayers.Format.XML.prototype.read.apply(this,[s.body]);var imported=doc.documentElement;if(sld.ownerDocument&&sld.ownerDocument.importNode){imported=sld.ownerDocument.importNode(imported,true);}
+sld.appendChild(imported);sld.appendChild(this.createElementDefaultNS("Name",s.name));if(s.title){sld.appendChild(this.createElementDefaultNS("Title",s.title));}
+style.appendChild(sld);}else{style.appendChild(this.createElementDefaultNS("Name",s.name));style.appendChild(this.createElementDefaultNS("Title",s.title));if(s['abstract']){style.appendChild(this.createElementDefaultNS("Abstract",s['abstract']));}}
+node.appendChild(style);}}
+return node;},write_wmc_OnlineResource:function(href){var node=this.createElementDefaultNS("OnlineResource");this.setAttributeNS(node,this.namespaces.xlink,"xlink:type","simple");this.setAttributeNS(node,this.namespaces.xlink,"xlink:href",href);return node;},CLASS_NAME:"OpenLayers.Format.WMC.v1"});OpenLayers.Format.WMSCapabilities.v1_1=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1,{readers:{"wms":OpenLayers.Util.applyDefaults({"WMT_MS_Capabilities":function(node,obj){this.readChildNodes(node,obj);},"Keyword":function(node,obj){if(obj.keywords){obj.keywords.push(this.getChildValue(node));}},"DescribeLayer":function(node,obj){obj.describelayer={formats:[]};this.readChildNodes(node,obj.describelayer);},"GetLegendGraphic":function(node,obj){obj.getlegendgraphic={formats:[]};this.readChildNodes(node,obj.getlegendgraphic);},"GetStyles":function(node,obj){obj.getstyles={formats:[]};this.readChildNodes(node,obj.getstyles);},"PutStyles":function(node,obj){obj.putstyles={formats:[]};this.readChildNodes(node,obj.putstyles);},"UserDefinedSymbolization":function(node,obj){var userSymbols={supportSLD:parseInt(node.getAttribute("SupportSLD"))==1,userLayer:parseInt(node.getAttribute("UserLayer"))==1,userStyle:parseInt(node.getAttribute("UserStyle"))==1,remoteWFS:parseInt(node.getAttribute("RemoteWFS"))==1};obj.userSymbols=userSymbols;},"LatLonBoundingBox":function(node,obj){obj.llbbox=[parseFloat(node.getAttribute("minx")),parseFloat(node.getAttribute("miny")),parseFloat(node.getAttribute("maxx")),parseFloat(node.getAttribute("maxy"))];},"BoundingBox":function(node,obj){var bbox=OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"].BoundingBox.apply(this,[node,obj]);bbox.srs=node.getAttribute("SRS");obj.bbox[bbox.srs]=bbox;},"ScaleHint":function(node,obj){var min=node.getAttribute("min");var max=node.getAttribute("max");var rad2=Math.pow(2,0.5);var ipm=OpenLayers.INCHES_PER_UNIT["m"];obj.maxScale=parseFloat(((min/rad2)*ipm*OpenLayers.DOTS_PER_INCH).toPrecision(13));obj.minScale=parseFloat(((max/rad2)*ipm*OpenLayers.DOTS_PER_INCH).toPrecision(13));},"Dimension":function(node,obj){var name=node.getAttribute("name").toLowerCase();var dim={name:name,units:node.getAttribute("units"),unitsymbol:node.getAttribute("unitSymbol")};obj.dimensions[dim.name]=dim;},"Extent":function(node,obj){var name=node.getAttribute("name").toLowerCase();if(name in obj["dimensions"]){var extent=obj.dimensions[name];extent.nearestVal=node.getAttribute("nearestValue")==="1";extent.multipleVal=node.getAttribute("multipleValues")==="1";extent.current=node.getAttribute("current")==="1";extent["default"]=node.getAttribute("default")||"";var values=this.getChildValue(node);extent.values=values.split(",");}}},OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"])},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1"});OpenLayers.Format.WMSCapabilities.v1_3=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1,{readers:{"wms":OpenLayers.Util.applyDefaults({"WMS_Capabilities":function(node,obj){this.readChildNodes(node,obj);},"LayerLimit":function(node,obj){obj.layerLimit=parseInt(this.getChildValue(node));},"MaxWidth":function(node,obj){obj.maxWidth=parseInt(this.getChildValue(node));},"MaxHeight":function(node,obj){obj.maxHeight=parseInt(this.getChildValue(node));},"BoundingBox":function(node,obj){var bbox=OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"].BoundingBox.apply(this,[node,obj]);bbox.srs=node.getAttribute("CRS");obj.bbox[bbox.srs]=bbox;},"CRS":function(node,obj){this.readers.wms.SRS.apply(this,[node,obj]);},"EX_GeographicBoundingBox":function(node,obj){obj.llbbox=[];this.readChildNodes(node,obj.llbbox);},"westBoundLongitude":function(node,obj){obj[0]=this.getChildValue(node);},"eastBoundLongitude":function(node,obj){obj[2]=this.getChildValue(node);},"southBoundLatitude":function(node,obj){obj[1]=this.getChildValue(node);},"northBoundLatitude":function(node,obj){obj[3]=this.getChildValue(node);},"MinScaleDenominator":function(node,obj){obj.maxScale=parseFloat(this.getChildValue(node)).toPrecision(16);},"MaxScaleDenominator":function(node,obj){obj.minScale=parseFloat(this.getChildValue(node)).toPrecision(16);},"Dimension":function(node,obj){var name=node.getAttribute("name").toLowerCase();var dim={name:name,units:node.getAttribute("units"),unitsymbol:node.getAttribute("unitSymbol"),nearestVal:node.getAttribute("nearestValue")==="1",multipleVal:node.getAttribute("multipleValues")==="1","default":node.getAttribute("default")||"",current:node.getAttribute("current")==="1",values:this.getChildValue(node).split(",")};obj.dimensions[dim.name]=dim;},"Keyword":function(node,obj){var keyword={value:this.getChildValue(node),vocabulary:node.getAttribute("vocabulary")};if(obj.keywords){obj.keywords.push(keyword);}}},OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"]),"sld":{"UserDefinedSymbolization":function(node,obj){this.readers.wms.UserDefinedSymbolization.apply(this,[node,obj]);obj.userSymbols.inlineFeature=parseInt(node.getAttribute("InlineFeature"))==1;obj.userSymbols.remoteWCS=parseInt(node.getAttribute("RemoteWCS"))==1;},"DescribeLayer":function(node,obj){this.readers.wms.DescribeLayer.apply(this,[node,obj]);},"GetLegendGraphic":function(node,obj){this.readers.wms.GetLegendGraphic.apply(this,[node,obj]);}}},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_3"});OpenLayers.Format.WMTSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1_1_0,{version:"1.0.0",namespaces:{ows:"http://www.opengis.net/ows/1.1",wmts:"http://www.opengis.net/wmts/1.0",xlink:"http://www.w3.org/1999/xlink"},yx:null,defaultPrefix:"wmts",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;var yx=OpenLayers.Util.extend({},OpenLayers.Format.WMTSCapabilities.prototype.yx);this.yx=OpenLayers.Util.extend(yx,this.yx);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+if(data&&data.nodeType==9){data=data.documentElement;}
+var capabilities={};this.readNode(data,capabilities);capabilities.version=this.version;return capabilities;},readers:{"wmts":{"Capabilities":function(node,obj){this.readChildNodes(node,obj);},"Contents":function(node,obj){obj.contents={};obj.contents.layers=[];obj.contents.tileMatrixSets={};this.readChildNodes(node,obj.contents);},"Layer":function(node,obj){var layer={styles:[],formats:[],tileMatrixSetLinks:[]};layer.layers=[];this.readChildNodes(node,layer);obj.layers.push(layer);},"Style":function(node,obj){var style={};style.isDefault=(node.getAttribute("isDefault")==="true");this.readChildNodes(node,style);obj.styles.push(style);},"Format":function(node,obj){obj.formats.push(this.getChildValue(node));},"TileMatrixSetLink":function(node,obj){var tileMatrixSetLink={};this.readChildNodes(node,tileMatrixSetLink);obj.tileMatrixSetLinks.push(tileMatrixSetLink);},"TileMatrixSet":function(node,obj){if(obj.layers){var tileMatrixSet={matrixIds:[]};this.readChildNodes(node,tileMatrixSet);obj.tileMatrixSets[tileMatrixSet.identifier]=tileMatrixSet;}else{obj.tileMatrixSet=this.getChildValue(node);}},"TileMatrix":function(node,obj){var tileMatrix={supportedCRS:obj.supportedCRS};this.readChildNodes(node,tileMatrix);obj.matrixIds.push(tileMatrix);},"ScaleDenominator":function(node,obj){obj.scaleDenominator=parseFloat(this.getChildValue(node));},"TopLeftCorner":function(node,obj){var topLeftCorner=this.getChildValue(node);var coords=topLeftCorner.split(" ");var yx;if(obj.supportedCRS){var crs=obj.supportedCRS.replace(/urn:ogc:def:crs:(\w+):.+:(\w+)$/,"urn:ogc:def:crs:$1::$2");yx=!!this.yx[crs];}
+if(yx){obj.topLeftCorner=new OpenLayers.LonLat(coords[1],coords[0]);}else{obj.topLeftCorner=new OpenLayers.LonLat(coords[0],coords[1]);}},"TileWidth":function(node,obj){obj.tileWidth=parseInt(this.getChildValue(node));},"TileHeight":function(node,obj){obj.tileHeight=parseInt(this.getChildValue(node));},"MatrixWidth":function(node,obj){obj.matrixWidth=parseInt(this.getChildValue(node));},"MatrixHeight":function(node,obj){obj.matrixHeight=parseInt(this.getChildValue(node));},"WSDL":function(node,obj){obj.wsdl={};obj.wsdl.href=node.getAttribute("xlink:href");},"ServiceMetadataURL":function(node,obj){obj.serviceMetadataUrl={};obj.serviceMetadataUrl.href=node.getAttribute("xlink:href");}},"ows":OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers["ows"]},CLASS_NAME:"OpenLayers.Format.WMTSCapabilities.v1_0_0"});OpenLayers.Layer.Boxes=OpenLayers.Class(OpenLayers.Layer.Markers,{initialize:function(name,options){OpenLayers.Layer.Markers.prototype.initialize.apply(this,arguments);},drawMarker:function(marker){var bounds=marker.bounds;var topleft=this.map.getLayerPxFromLonLat(new OpenLayers.LonLat(bounds.left,bounds.top));var botright=this.map.getLayerPxFromLonLat(new OpenLayers.LonLat(bounds.right,bounds.bottom));if(botright==null||topleft==null){marker.display(false);}else{var sz=new OpenLayers.Size(Math.max(1,botright.x-topleft.x),Math.max(1,botright.y-topleft.y));var markerDiv=marker.draw(topleft,sz);if(!marker.drawn){this.div.appendChild(markerDiv);marker.drawn=true;}}},removeMarker:function(marker){OpenLayers.Util.removeItem(this.markers,marker);if((marker.div!=null)&&(marker.div.parentNode==this.div)){this.div.removeChild(marker.div);}},CLASS_NAME:"OpenLayers.Layer.Boxes"});OpenLayers.Layer.GeoRSS=OpenLayers.Class(OpenLayers.Layer.Markers,{location:null,features:null,formatOptions:null,selectedFeature:null,icon:null,popupSize:null,useFeedTitle:true,initialize:function(name,location,options){OpenLayers.Layer.Markers.prototype.initialize.apply(this,[name,options]);this.location=location;this.features=[];},destroy:function(){OpenLayers.Layer.Markers.prototype.destroy.apply(this,arguments);this.clearFeatures();this.features=null;},loadRSS:function(){if(!this.loaded){this.events.triggerEvent("loadstart");OpenLayers.Request.GET({url:this.location,success:this.parseData,scope:this});this.loaded=true;}},moveTo:function(bounds,zoomChanged,minor){OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadRSS();}},parseData:function(ajaxRequest){var doc=ajaxRequest.responseXML;if(!doc||!doc.documentElement){doc=OpenLayers.Format.XML.prototype.read(ajaxRequest.responseText);}
+if(this.useFeedTitle){var name=null;try{name=doc.getElementsByTagNameNS('*','title')[0].firstChild.nodeValue;}
+catch(e){name=doc.getElementsByTagName('title')[0].firstChild.nodeValue;}
+if(name){this.setName(name);}}
+var options={};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
+var format=new OpenLayers.Format.GeoRSS(options);var features=format.read(doc);for(var i=0,len=features.length;i<len;i++){var data={};var feature=features[i];if(!feature.geometry){continue;}
+var title=feature.attributes.title?feature.attributes.title:"Untitled";var description=feature.attributes.description?feature.attributes.description:"No description.";var link=feature.attributes.link?feature.attributes.link:"";var location=feature.geometry.getBounds().getCenterLonLat();data.icon=this.icon==null?OpenLayers.Marker.defaultIcon():this.icon.clone();data.popupSize=this.popupSize?this.popupSize.clone():new OpenLayers.Size(250,120);if(title||description){data.title=title;data.description=description;var contentHTML='<div class="olLayerGeoRSSClose">[x]</div>';contentHTML+='<div class="olLayerGeoRSSTitle">';if(link){contentHTML+='<a class="link" href="'+link+'" target="_blank">';}
+contentHTML+=title;if(link){contentHTML+='</a>';}
+contentHTML+='</div>';contentHTML+='<div style="" class="olLayerGeoRSSDescription">';contentHTML+=description;contentHTML+='</div>';data['popupContentHTML']=contentHTML;}
+var feature=new OpenLayers.Feature(this,location,data);this.features.push(feature);var marker=feature.createMarker();marker.events.register('click',feature,this.markerClick);this.addMarker(marker);}
+this.events.triggerEvent("loadend");},markerClick:function(evt){var sameMarkerClicked=(this==this.layer.selectedFeature);this.layer.selectedFeature=(!sameMarkerClicked)?this:null;for(var i=0,len=this.layer.map.popups.length;i<len;i++){this.layer.map.removePopup(this.layer.map.popups[i]);}
+if(!sameMarkerClicked){var popup=this.createPopup();OpenLayers.Event.observe(popup.div,"click",OpenLayers.Function.bind(function(){for(var i=0,len=this.layer.map.popups.length;i<len;i++){this.layer.map.removePopup(this.layer.map.popups[i]);}},this));this.layer.map.addPopup(popup);}
+OpenLayers.Event.stop(evt);},clearFeatures:function(){if(this.features!=null){while(this.features.length>0){var feature=this.features[0];OpenLayers.Util.removeItem(this.features,feature);feature.destroy();}}},CLASS_NAME:"OpenLayers.Layer.GeoRSS"});OpenLayers.Layer.Google=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:0,MAX_ZOOM_LEVEL:21,RESOLUTIONS:[1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125,0.00002145767211914062,0.00001072883605957031,0.00000536441802978515,0.00000268220901489257,0.0000013411045074462891,0.00000067055225372314453],type:null,wrapDateLine:true,sphericalMercator:false,version:null,initialize:function(name,options){options=options||{};if(!options.version){options.version=typeof GMap2==="function"?"2":"3";}
+var mixin=OpenLayers.Layer.Google["v"+
+options.version.replace(/\./g,"_")];if(mixin){OpenLayers.Util.applyDefaults(options,mixin);}else{throw"Unsupported Google Maps API version: "+options.version;}
+OpenLayers.Util.applyDefaults(options,mixin.DEFAULTS);if(options.maxExtent){options.maxExtent=options.maxExtent.clone();}
+OpenLayers.Layer.EventPane.prototype.initialize.apply(this,[name,options]);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,[name,options]);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();}},clone:function(){return new OpenLayers.Layer.Google(this.name,this.getOptions());},setVisibility:function(visible){var opacity=this.opacity==null?1:this.opacity;OpenLayers.Layer.EventPane.prototype.setVisibility.apply(this,arguments);this.setOpacity(opacity);},display:function(visible){if(!this._dragging){this.setGMapVisibility(visible);}
+OpenLayers.Layer.EventPane.prototype.display.apply(this,arguments);},moveTo:function(bounds,zoomChanged,dragging){this._dragging=dragging;OpenLayers.Layer.EventPane.prototype.moveTo.apply(this,arguments);delete this._dragging;},setOpacity:function(opacity){if(opacity!==this.opacity){if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"opacity"});}
+this.opacity=opacity;}
+if(this.getVisibility()){var container=this.getMapContainer();OpenLayers.Util.modifyDOMElement(container,null,null,null,null,null,null,opacity);}},destroy:function(){if(this.map){this.setGMapVisibility(false);var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache&&cache.count<=1){this.removeGMapElements();}}
+OpenLayers.Layer.EventPane.prototype.destroy.apply(this,arguments);},removeGMapElements:function(){var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){var container=this.mapObject&&this.getMapContainer();if(container&&container.parentNode){container.parentNode.removeChild(container);}
+var termsOfUse=cache.termsOfUse;if(termsOfUse&&termsOfUse.parentNode){termsOfUse.parentNode.removeChild(termsOfUse);}
+var poweredBy=cache.poweredBy;if(poweredBy&&poweredBy.parentNode){poweredBy.parentNode.removeChild(poweredBy);}}},removeMap:function(map){if(this.visibility&&this.mapObject){this.setGMapVisibility(false);}
+var cache=OpenLayers.Layer.Google.cache[map.id];if(cache){if(cache.count<=1){this.removeGMapElements();delete OpenLayers.Layer.Google.cache[map.id];}else{--cache.count;}}
+delete this.termsOfUse;delete this.poweredBy;delete this.mapObject;delete this.dragObject;OpenLayers.Layer.EventPane.prototype.removeMap.apply(this,arguments);},getOLBoundsFromMapObjectBounds:function(moBounds){var olBounds=null;if(moBounds!=null){var sw=moBounds.getSouthWest();var ne=moBounds.getNorthEast();if(this.sphericalMercator){sw=this.forwardMercator(sw.lng(),sw.lat());ne=this.forwardMercator(ne.lng(),ne.lat());}else{sw=new OpenLayers.LonLat(sw.lng(),sw.lat());ne=new OpenLayers.LonLat(ne.lng(),ne.lat());}
+olBounds=new OpenLayers.Bounds(sw.lon,sw.lat,ne.lon,ne.lat);}
+return olBounds;},getWarningHTML:function(){return OpenLayers.i18n("googleWarning");},getMapObjectCenter:function(){return this.mapObject.getCenter();},getMapObjectZoom:function(){return this.mapObject.getZoom();},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.lng(),moLonLat.lat()).lon:moLonLat.lng();},getLatitudeFromMapObjectLonLat:function(moLonLat){var lat=this.sphericalMercator?this.forwardMercator(moLonLat.lng(),moLonLat.lat()).lat:moLonLat.lat();return lat;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},CLASS_NAME:"OpenLayers.Layer.Google"});OpenLayers.Layer.Google.cache={};OpenLayers.Layer.Google.v2={termsOfUse:null,poweredBy:null,dragObject:null,loadMapObject:function(){if(!this.type){this.type=G_NORMAL_MAP;}
+var mapObject,termsOfUse,poweredBy;var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){mapObject=cache.mapObject;termsOfUse=cache.termsOfUse;poweredBy=cache.poweredBy;++cache.count;}else{var container=this.map.viewPortDiv;var div=document.createElement("div");div.id=this.map.id+"_GMap2Container";div.style.position="absolute";div.style.width="100%";div.style.height="100%";container.appendChild(div);try{mapObject=new GMap2(div);termsOfUse=div.lastChild;container.appendChild(termsOfUse);termsOfUse.style.zIndex="1100";termsOfUse.style.right="";termsOfUse.style.bottom="";termsOfUse.className="olLayerGoogleCopyright";poweredBy=div.lastChild;container.appendChild(poweredBy);poweredBy.style.zIndex="1100";poweredBy.style.right="";poweredBy.style.bottom="";poweredBy.className="olLayerGooglePoweredBy gmnoprint";}catch(e){throw(e);}
+OpenLayers.Layer.Google.cache[this.map.id]={mapObject:mapObject,termsOfUse:termsOfUse,poweredBy:poweredBy,count:1};}
+this.mapObject=mapObject;this.termsOfUse=termsOfUse;this.poweredBy=poweredBy;if(OpenLayers.Util.indexOf(this.mapObject.getMapTypes(),this.type)===-1){this.mapObject.addMapType(this.type);}
+if(typeof mapObject.getDragObject=="function"){this.dragObject=mapObject.getDragObject();}else{this.dragPanMapObject=null;}
+if(this.isBaseLayer===false){this.setGMapVisibility(this.div.style.display!=="none");}},onMapResize:function(){if(this.visibility&&this.mapObject.isLoaded()){this.mapObject.checkResize();}else{if(!this._resized){var layer=this;var handle=GEvent.addListener(this.mapObject,"load",function(){GEvent.removeListener(handle);delete layer._resized;layer.mapObject.checkResize();layer.moveTo(layer.map.getCenter(),layer.map.getZoom());});}
+this._resized=true;}},setGMapVisibility:function(visible){var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){var container=this.mapObject.getContainer();if(visible===true){this.mapObject.setMapType(this.type);container.style.display="";this.termsOfUse.style.left="";this.termsOfUse.style.display="";this.poweredBy.style.display="";cache.displayed=this.id;}else{if(cache.displayed===this.id){delete cache.displayed;}
+if(!cache.displayed){container.style.display="none";this.termsOfUse.style.display="none";this.termsOfUse.style.left="-9999px";this.poweredBy.style.display="none";}}}},getMapContainer:function(){return this.mapObject.getContainer();},getMapObjectBoundsFromOLBounds:function(olBounds){var moBounds=null;if(olBounds!=null){var sw=this.sphericalMercator?this.inverseMercator(olBounds.bottom,olBounds.left):new OpenLayers.LonLat(olBounds.bottom,olBounds.left);var ne=this.sphericalMercator?this.inverseMercator(olBounds.top,olBounds.right):new OpenLayers.LonLat(olBounds.top,olBounds.right);moBounds=new GLatLngBounds(new GLatLng(sw.lat,sw.lon),new GLatLng(ne.lat,ne.lon));}
+return moBounds;},setMapObjectCenter:function(center,zoom){this.mapObject.setCenter(center,zoom);},dragPanMapObject:function(dX,dY){this.dragObject.moveBy(new GSize(-dX,dY));},getMapObjectLonLatFromMapObjectPixel:function(moPixel){return this.mapObject.fromContainerPixelToLatLng(moPixel);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.fromLatLngToContainerPixel(moLonLat);},getMapObjectZoomFromMapObjectBounds:function(moBounds){return this.mapObject.getBoundsZoomLevel(moBounds);},getMapObjectLonLatFromLonLat:function(lon,lat){var gLatLng;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);gLatLng=new GLatLng(lonlat.lat,lonlat.lon);}else{gLatLng=new GLatLng(lat,lon);}
+return gLatLng;},getMapObjectPixelFromXY:function(x,y){return new GPoint(x,y);}};OpenLayers.Layer.Grid=OpenLayers.Class(OpenLayers.Layer.HTTPRequest,{tileSize:null,grid:null,singleTile:false,ratio:1.5,buffer:2,numLoadingTiles:0,initialize:function(name,url,params,options){OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,arguments);this.events.addEventType("tileloaded");this.grid=[];},destroy:function(){this.clearGrid();this.grid=null;this.tileSize=null;OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this,arguments);},clearGrid:function(){if(this.grid){for(var iRow=0,len=this.grid.length;iRow<len;iRow++){var row=this.grid[iRow];for(var iCol=0,clen=row.length;iCol<clen;iCol++){var tile=row[iCol];this.removeTileMonitoringHooks(tile);tile.destroy();}}
+this.grid=[];}},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Grid(this.name,this.url,this.params,this.getOptions());}
+obj=OpenLayers.Layer.HTTPRequest.prototype.clone.apply(this,[obj]);if(this.tileSize!=null){obj.tileSize=this.tileSize.clone();}
+obj.grid=[];return obj;},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.HTTPRequest.prototype.moveTo.apply(this,arguments);bounds=bounds||this.map.getExtent();if(bounds!=null){var forceReTile=!this.grid.length||zoomChanged;var tilesBounds=this.getTilesBounds();if(this.singleTile){if(forceReTile||(!dragging&&!tilesBounds.containsBounds(bounds))){this.initSingleTile(bounds);}}else{if(forceReTile||!tilesBounds.containsBounds(bounds,true)){this.initGriddedTiles(bounds);}else{this.moveGriddedTiles(bounds);}}}},setTileSize:function(size){if(this.singleTile){size=this.map.getSize();size.h=parseInt(size.h*this.ratio);size.w=parseInt(size.w*this.ratio);}
+OpenLayers.Layer.HTTPRequest.prototype.setTileSize.apply(this,[size]);},getGridBounds:function(){var msg="The getGridBounds() function is deprecated. It will be "+"removed in 3.0. Please use getTilesBounds() instead.";OpenLayers.Console.warn(msg);return this.getTilesBounds();},getTilesBounds:function(){var bounds=null;if(this.grid.length){var bottom=this.grid.length-1;var bottomLeftTile=this.grid[bottom][0];var right=this.grid[0].length-1;var topRightTile=this.grid[0][right];bounds=new OpenLayers.Bounds(bottomLeftTile.bounds.left,bottomLeftTile.bounds.bottom,topRightTile.bounds.right,topRightTile.bounds.top);}
+return bounds;},initSingleTile:function(bounds){var center=bounds.getCenterLonLat();var tileWidth=bounds.getWidth()*this.ratio;var tileHeight=bounds.getHeight()*this.ratio;var tileBounds=new OpenLayers.Bounds(center.lon-(tileWidth/2),center.lat-(tileHeight/2),center.lon+(tileWidth/2),center.lat+(tileHeight/2));var ul=new OpenLayers.LonLat(tileBounds.left,tileBounds.top);var px=this.map.getLayerPxFromLonLat(ul);if(!this.grid.length){this.grid[0]=[];}
+var tile=this.grid[0][0];if(!tile){tile=this.addTile(tileBounds,px);this.addTileMonitoringHooks(tile);tile.draw();this.grid[0][0]=tile;}else{tile.moveTo(tileBounds,px);}
+this.removeExcessTiles(1,1);},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left-extent.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=extent.left+tilecol*tilelon;var offsetlat=bounds.top-(extent.bottom+tilelat);var tilerow=Math.ceil(offsetlat/tilelat)+this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=-tilerowremain*this.tileSize.h;var tileoffsetlat=extent.bottom+tilerow*tilelat;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},initGriddedTiles:function(bounds){var viewSize=this.map.getSize();var minRows=Math.ceil(viewSize.h/this.tileSize.h)+
+Math.max(1,2*this.buffer);var minCols=Math.ceil(viewSize.w/this.tileSize.w)+
+Math.max(1,2*this.buffer);var extent=this.getMaxExtent();var resolution=this.map.getResolution();var tileLayout=this.calculateGridLayout(bounds,extent,resolution);var tileoffsetx=Math.round(tileLayout.tileoffsetx);var tileoffsety=Math.round(tileLayout.tileoffsety);var tileoffsetlon=tileLayout.tileoffsetlon;var tileoffsetlat=tileLayout.tileoffsetlat;var tilelon=tileLayout.tilelon;var tilelat=tileLayout.tilelat;this.origin=new OpenLayers.Pixel(tileoffsetx,tileoffsety);var startX=tileoffsetx;var startLon=tileoffsetlon;var rowidx=0;var layerContainerDivLeft=parseInt(this.map.layerContainerDiv.style.left);var layerContainerDivTop=parseInt(this.map.layerContainerDiv.style.top);do{var row=this.grid[rowidx++];if(!row){row=[];this.grid.push(row);}
+tileoffsetlon=startLon;tileoffsetx=startX;var colidx=0;do{var tileBounds=new OpenLayers.Bounds(tileoffsetlon,tileoffsetlat,tileoffsetlon+tilelon,tileoffsetlat+tilelat);var x=tileoffsetx;x-=layerContainerDivLeft;var y=tileoffsety;y-=layerContainerDivTop;var px=new OpenLayers.Pixel(x,y);var tile=row[colidx++];if(!tile){tile=this.addTile(tileBounds,px);this.addTileMonitoringHooks(tile);row.push(tile);}else{tile.moveTo(tileBounds,px,false);}
+tileoffsetlon+=tilelon;tileoffsetx+=this.tileSize.w;}while((tileoffsetlon<=bounds.right+tilelon*this.buffer)||colidx<minCols);tileoffsetlat-=tilelat;tileoffsety+=this.tileSize.h;}while((tileoffsetlat>=bounds.bottom-tilelat*this.buffer)||rowidx<minRows);this.removeExcessTiles(rowidx,colidx);this.spiralTileLoad();},getMaxExtent:function(){return this.maxExtent;},spiralTileLoad:function(){var tileQueue=[];var directions=["right","down","left","up"];var iRow=0;var iCell=-1;var direction=OpenLayers.Util.indexOf(directions,"right");var directionsTried=0;while(directionsTried<directions.length){var testRow=iRow;var testCell=iCell;switch(directions[direction]){case"right":testCell++;break;case"down":testRow++;break;case"left":testCell--;break;case"up":testRow--;break;}
+var tile=null;if((testRow<this.grid.length)&&(testRow>=0)&&(testCell<this.grid[0].length)&&(testCell>=0)){tile=this.grid[testRow][testCell];}
+if((tile!=null)&&(!tile.queued)){tileQueue.unshift(tile);tile.queued=true;directionsTried=0;iRow=testRow;iCell=testCell;}else{direction=(direction+1)%4;directionsTried++;}}
+for(var i=0,len=tileQueue.length;i<len;i++){var tile=tileQueue[i];tile.draw();tile.queued=false;}},addTile:function(bounds,position){},addTileMonitoringHooks:function(tile){tile.onLoadStart=function(){if(this.numLoadingTiles==0){this.events.triggerEvent("loadstart");}
+this.numLoadingTiles++;};tile.events.register("loadstart",this,tile.onLoadStart);tile.onLoadEnd=function(){this.numLoadingTiles--;this.events.triggerEvent("tileloaded");if(this.numLoadingTiles==0){this.events.triggerEvent("loadend");}};tile.events.register("loadend",this,tile.onLoadEnd);tile.events.register("unload",this,tile.onLoadEnd);},removeTileMonitoringHooks:function(tile){tile.unload();tile.events.un({"loadstart":tile.onLoadStart,"loadend":tile.onLoadEnd,"unload":tile.onLoadEnd,scope:this});},moveGriddedTiles:function(bounds){var buffer=this.buffer||1;while(true){var tlLayer=this.grid[0][0].position;var tlViewPort=this.map.getViewPortPxFromLayerPx(tlLayer);if(tlViewPort.x>-this.tileSize.w*(buffer-1)){this.shiftColumn(true);}else if(tlViewPort.x<-this.tileSize.w*buffer){this.shiftColumn(false);}else if(tlViewPort.y>-this.tileSize.h*(buffer-1)){this.shiftRow(true);}else if(tlViewPort.y<-this.tileSize.h*buffer){this.shiftRow(false);}else{break;}};},shiftRow:function(prepend){var modelRowIndex=(prepend)?0:(this.grid.length-1);var grid=this.grid;var modelRow=grid[modelRowIndex];var resolution=this.map.getResolution();var deltaY=(prepend)?-this.tileSize.h:this.tileSize.h;var deltaLat=resolution*-deltaY;var row=(prepend)?grid.pop():grid.shift();for(var i=0,len=modelRow.length;i<len;i++){var modelTile=modelRow[i];var bounds=modelTile.bounds.clone();var position=modelTile.position.clone();bounds.bottom=bounds.bottom+deltaLat;bounds.top=bounds.top+deltaLat;position.y=position.y+deltaY;row[i].moveTo(bounds,position);}
+if(prepend){grid.unshift(row);}else{grid.push(row);}},shiftColumn:function(prepend){var deltaX=(prepend)?-this.tileSize.w:this.tileSize.w;var resolution=this.map.getResolution();var deltaLon=resolution*deltaX;for(var i=0,len=this.grid.length;i<len;i++){var row=this.grid[i];var modelTileIndex=(prepend)?0:(row.length-1);var modelTile=row[modelTileIndex];var bounds=modelTile.bounds.clone();var position=modelTile.position.clone();bounds.left=bounds.left+deltaLon;bounds.right=bounds.right+deltaLon;position.x=position.x+deltaX;var tile=prepend?this.grid[i].pop():this.grid[i].shift();tile.moveTo(bounds,position);if(prepend){row.unshift(tile);}else{row.push(tile);}}},removeExcessTiles:function(rows,columns){while(this.grid.length>rows){var row=this.grid.pop();for(var i=0,l=row.length;i<l;i++){var tile=row[i];this.removeTileMonitoringHooks(tile);tile.destroy();}}
+while(this.grid[0].length>columns){for(var i=0,l=this.grid.length;i<l;i++){var row=this.grid[i];var tile=row.pop();this.removeTileMonitoringHooks(tile);tile.destroy();}}},onMapResize:function(){if(this.singleTile){this.clearGrid();this.setTileSize();}},getTileBounds:function(viewPortPx){var maxExtent=this.maxExtent;var resolution=this.getResolution();var tileMapWidth=resolution*this.tileSize.w;var tileMapHeight=resolution*this.tileSize.h;var mapPoint=this.getLonLatFromViewPortPx(viewPortPx);var tileLeft=maxExtent.left+(tileMapWidth*Math.floor((mapPoint.lon-
+maxExtent.left)/tileMapWidth));var tileBottom=maxExtent.bottom+(tileMapHeight*Math.floor((mapPoint.lat-
+maxExtent.bottom)/tileMapHeight));return new OpenLayers.Bounds(tileLeft,tileBottom,tileLeft+tileMapWidth,tileBottom+tileMapHeight);},CLASS_NAME:"OpenLayers.Layer.Grid"});OpenLayers.Layer.MultiMap=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:1,MAX_ZOOM_LEVEL:17,RESOLUTIONS:[9,1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125],type:null,initialize:function(name,options){OpenLayers.Layer.EventPane.prototype.initialize.apply(this,arguments);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,arguments);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();this.RESOLUTIONS.unshift(10);}},loadMapObject:function(){try{this.mapObject=new MultimapViewer(this.div);}catch(e){}},getWarningHTML:function(){return OpenLayers.i18n("getLayerWarning",{'layerType':"MM",'layerLib':"MultiMap"});},setMapObjectCenter:function(center,zoom){this.mapObject.goToPosition(center,zoom);},getMapObjectCenter:function(){return this.mapObject.getCurrentPosition();},getMapObjectZoom:function(){return this.mapObject.getZoomFactor();},getMapObjectLonLatFromMapObjectPixel:function(moPixel){moPixel.x=moPixel.x-(this.map.getSize().w/2);moPixel.y=moPixel.y-(this.map.getSize().h/2);return this.mapObject.getMapPositionAt(moPixel);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.geoPosToContainerPixels(moLonLat);},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.lon,moLonLat.lat).lon:moLonLat.lon;},getLatitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.lon,moLonLat.lat).lat:moLonLat.lat;},getMapObjectLonLatFromLonLat:function(lon,lat){var mmLatLon;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);mmLatLon=new MMLatLon(lonlat.lat,lonlat.lon);}else{mmLatLon=new MMLatLon(lat,lon);}
+return mmLatLon;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},getMapObjectPixelFromXY:function(x,y){return new MMPoint(x,y);},CLASS_NAME:"OpenLayers.Layer.MultiMap"});OpenLayers.Layer.VirtualEarth=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:1,MAX_ZOOM_LEVEL:19,RESOLUTIONS:[1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125,0.00002145767211914062,0.00001072883605957031,0.00000536441802978515],type:null,wrapDateLine:true,sphericalMercator:false,animationEnabled:true,initialize:function(name,options){OpenLayers.Layer.EventPane.prototype.initialize.apply(this,arguments);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,arguments);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();}},loadMapObject:function(){var veDiv=OpenLayers.Util.createDiv(this.name);var sz=this.map.getSize();veDiv.style.width=sz.w+"px";veDiv.style.height=sz.h+"px";this.div.appendChild(veDiv);try{this.mapObject=new VEMap(this.name);}catch(e){}
+if(this.mapObject!=null){try{this.mapObject.LoadMap(null,null,this.type,true);this.mapObject.AttachEvent("onmousedown",OpenLayers.Function.True);}catch(e){}
+this.mapObject.HideDashboard();if(typeof this.mapObject.SetAnimationEnabled=="function"){this.mapObject.SetAnimationEnabled(this.animationEnabled);}}
+if(!this.mapObject||!this.mapObject.vemapcontrol||!this.mapObject.vemapcontrol.PanMap||(typeof this.mapObject.vemapcontrol.PanMap!="function")){this.dragPanMapObject=null;}},onMapResize:function(){this.mapObject.Resize(this.map.size.w,this.map.size.h);},getWarningHTML:function(){return OpenLayers.i18n("getLayerWarning",{'layerType':'VE','layerLib':'VirtualEarth'});},setMapObjectCenter:function(center,zoom){this.mapObject.SetCenterAndZoom(center,zoom);},getMapObjectCenter:function(){return this.mapObject.GetCenter();},dragPanMapObject:function(dX,dY){this.mapObject.vemapcontrol.PanMap(dX,-dY);},getMapObjectZoom:function(){return this.mapObject.GetZoomLevel();},getMapObjectLonLatFromMapObjectPixel:function(moPixel){return(typeof VEPixel!='undefined')?this.mapObject.PixelToLatLong(moPixel):this.mapObject.PixelToLatLong(moPixel.x,moPixel.y);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.LatLongToPixel(moLonLat);},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Longitude,moLonLat.Latitude).lon:moLonLat.Longitude;},getLatitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Longitude,moLonLat.Latitude).lat:moLonLat.Latitude;},getMapObjectLonLatFromLonLat:function(lon,lat){var veLatLong;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);veLatLong=new VELatLong(lonlat.lat,lonlat.lon);}else{veLatLong=new VELatLong(lat,lon);}
+return veLatLong;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},getMapObjectPixelFromXY:function(x,y){return(typeof VEPixel!='undefined')?new VEPixel(x,y):new Msn.VE.Pixel(x,y);},CLASS_NAME:"OpenLayers.Layer.VirtualEarth"});OpenLayers.Layer.Yahoo=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:0,MAX_ZOOM_LEVEL:17,RESOLUTIONS:[1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125,0.00002145767211914062,0.00001072883605957031],type:null,wrapDateLine:true,sphericalMercator:false,initialize:function(name,options){OpenLayers.Layer.EventPane.prototype.initialize.apply(this,arguments);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,arguments);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();}},loadMapObject:function(){try{var size=this.getMapObjectSizeFromOLSize(this.map.getSize());this.mapObject=new YMap(this.div,this.type,size);this.mapObject.disableKeyControls();this.mapObject.disableDragMap();if(!this.mapObject.moveByXY||(typeof this.mapObject.moveByXY!="function")){this.dragPanMapObject=null;}}catch(e){}},onMapResize:function(){try{var size=this.getMapObjectSizeFromOLSize(this.map.getSize());this.mapObject.resizeTo(size);}catch(e){}},setMap:function(map){OpenLayers.Layer.EventPane.prototype.setMap.apply(this,arguments);this.map.events.register("moveend",this,this.fixYahooEventPane);},fixYahooEventPane:function(){var yahooEventPane=OpenLayers.Util.getElement("ygddfdiv");if(yahooEventPane!=null){if(yahooEventPane.parentNode!=null){yahooEventPane.parentNode.removeChild(yahooEventPane);}
+this.map.events.unregister("moveend",this,this.fixYahooEventPane);}},getWarningHTML:function(){return OpenLayers.i18n("getLayerWarning",{'layerType':'Yahoo','layerLib':'Yahoo'});},getOLZoomFromMapObjectZoom:function(moZoom){var zoom=null;if(moZoom!=null){zoom=OpenLayers.Layer.FixedZoomLevels.prototype.getOLZoomFromMapObjectZoom.apply(this,[moZoom]);zoom=18-zoom;}
+return zoom;},getMapObjectZoomFromOLZoom:function(olZoom){var zoom=null;if(olZoom!=null){zoom=OpenLayers.Layer.FixedZoomLevels.prototype.getMapObjectZoomFromOLZoom.apply(this,[olZoom]);zoom=18-zoom;}
+return zoom;},setMapObjectCenter:function(center,zoom){this.mapObject.drawZoomAndCenter(center,zoom);},getMapObjectCenter:function(){return this.mapObject.getCenterLatLon();},dragPanMapObject:function(dX,dY){this.mapObject.moveByXY({'x':-dX,'y':dY});},getMapObjectZoom:function(){return this.mapObject.getZoomLevel();},getMapObjectLonLatFromMapObjectPixel:function(moPixel){return this.mapObject.convertXYLatLon(moPixel);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.convertLatLonXY(moLonLat);},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Lon,moLonLat.Lat).lon:moLonLat.Lon;},getLatitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Lon,moLonLat.Lat).lat:moLonLat.Lat;},getMapObjectLonLatFromLonLat:function(lon,lat){var yLatLong;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);yLatLong=new YGeoPoint(lonlat.lat,lonlat.lon);}else{yLatLong=new YGeoPoint(lat,lon);}
+return yLatLong;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},getMapObjectPixelFromXY:function(x,y){return new YCoordPoint(x,y);},getMapObjectSizeFromOLSize:function(olSize){return new YSize(olSize.w,olSize.h);},CLASS_NAME:"OpenLayers.Layer.Yahoo"});OpenLayers.Style=OpenLayers.Class({id:null,name:null,title:null,description:null,layerName:null,isDefault:false,rules:null,context:null,defaultStyle:null,defaultsPerSymbolizer:false,propertyStyles:null,initialize:function(style,options){OpenLayers.Util.extend(this,options);this.rules=[];if(options&&options.rules){this.addRules(options.rules);}
+this.setDefaultStyle(style||OpenLayers.Feature.Vector.style["default"]);this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){for(var i=0,len=this.rules.length;i<len;i++){this.rules[i].destroy();this.rules[i]=null;}
+this.rules=null;this.defaultStyle=null;},createSymbolizer:function(feature){var style=this.defaultsPerSymbolizer?{}:this.createLiterals(OpenLayers.Util.extend({},this.defaultStyle),feature);var rules=this.rules;var rule,context;var elseRules=[];var appliedRules=false;for(var i=0,len=rules.length;i<len;i++){rule=rules[i];var applies=rule.evaluate(feature);if(applies){if(rule instanceof OpenLayers.Rule&&rule.elseFilter){elseRules.push(rule);}else{appliedRules=true;this.applySymbolizer(rule,style,feature);}}}
+if(appliedRules==false&&elseRules.length>0){appliedRules=true;for(var i=0,len=elseRules.length;i<len;i++){this.applySymbolizer(elseRules[i],style,feature);}}
+if(rules.length>0&&appliedRules==false){style.display="none";}
+return style;},applySymbolizer:function(rule,style,feature){var symbolizerPrefix=feature.geometry?this.getSymbolizerPrefix(feature.geometry):OpenLayers.Style.SYMBOLIZER_PREFIXES[0];var symbolizer=rule.symbolizer[symbolizerPrefix]||rule.symbolizer;if(this.defaultsPerSymbolizer===true){var defaults=this.defaultStyle;OpenLayers.Util.applyDefaults(symbolizer,{pointRadius:defaults.pointRadius});if(symbolizer.stroke===true||symbolizer.graphic===true){OpenLayers.Util.applyDefaults(symbolizer,{strokeWidth:defaults.strokeWidth,strokeColor:defaults.strokeColor,strokeOpacity:defaults.strokeOpacity,strokeDashstyle:defaults.strokeDashstyle,strokeLinecap:defaults.strokeLinecap});}
+if(symbolizer.fill===true||symbolizer.graphic===true){OpenLayers.Util.applyDefaults(symbolizer,{fillColor:defaults.fillColor,fillOpacity:defaults.fillOpacity});}
+if(symbolizer.graphic===true){OpenLayers.Util.applyDefaults(symbolizer,{pointRadius:this.defaultStyle.pointRadius,externalGraphic:this.defaultStyle.externalGraphic,graphicName:this.defaultStyle.graphicName,graphicOpacity:this.defaultStyle.graphicOpacity,graphicWidth:this.defaultStyle.graphicWidth,graphicHeight:this.defaultStyle.graphicHeight,graphicXOffset:this.defaultStyle.graphicXOffset,graphicYOffset:this.defaultStyle.graphicYOffset});}}
+return this.createLiterals(OpenLayers.Util.extend(style,symbolizer),feature);},createLiterals:function(style,feature){var context=OpenLayers.Util.extend({},feature.attributes||feature.data);OpenLayers.Util.extend(context,this.context);for(var i in this.propertyStyles){style[i]=OpenLayers.Style.createLiteral(style[i],context,feature,i);}
+return style;},findPropertyStyles:function(){var propertyStyles={};var style=this.defaultStyle;this.addPropertyStyles(propertyStyles,style);var rules=this.rules;var symbolizer,value;for(var i=0,len=rules.length;i<len;i++){symbolizer=rules[i].symbolizer;for(var key in symbolizer){value=symbolizer[key];if(typeof value=="object"){this.addPropertyStyles(propertyStyles,value);}else{this.addPropertyStyles(propertyStyles,symbolizer);break;}}}
+return propertyStyles;},addPropertyStyles:function(propertyStyles,symbolizer){var property;for(var key in symbolizer){property=symbolizer[key];if(typeof property=="string"&&property.match(/\$\{\w+\}/)){propertyStyles[key]=true;}}
+return propertyStyles;},addRules:function(rules){Array.prototype.push.apply(this.rules,rules);this.propertyStyles=this.findPropertyStyles();},setDefaultStyle:function(style){this.defaultStyle=style;this.propertyStyles=this.findPropertyStyles();},getSymbolizerPrefix:function(geometry){var prefixes=OpenLayers.Style.SYMBOLIZER_PREFIXES;for(var i=0,len=prefixes.length;i<len;i++){if(geometry.CLASS_NAME.indexOf(prefixes[i])!=-1){return prefixes[i];}}},clone:function(){var options=OpenLayers.Util.extend({},this);if(this.rules){options.rules=[];for(var i=0,len=this.rules.length;i<len;++i){options.rules.push(this.rules[i].clone());}}
+options.context=this.context&&OpenLayers.Util.extend({},this.context);var defaultStyle=OpenLayers.Util.extend({},this.defaultStyle);return new OpenLayers.Style(defaultStyle,options);},CLASS_NAME:"OpenLayers.Style"});OpenLayers.Style.createLiteral=function(value,context,feature,property){if(typeof value=="string"&&value.indexOf("${")!=-1){value=OpenLayers.String.format(value,context,[feature,property]);value=(isNaN(value)||!value)?value:parseFloat(value);}
+return value;};OpenLayers.Style.SYMBOLIZER_PREFIXES=['Point','Line','Polygon','Text','Raster'];OpenLayers.Control.Navigation=OpenLayers.Class(OpenLayers.Control,{dragPan:null,dragPanOptions:null,documentDrag:false,zoomBox:null,zoomBoxEnabled:true,zoomWheelEnabled:true,mouseWheelOptions:null,handleRightClicks:false,zoomBoxKeyMask:OpenLayers.Handler.MOD_SHIFT,autoActivate:true,initialize:function(options){this.handlers={};OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){this.deactivate();if(this.dragPan){this.dragPan.destroy();}
+this.dragPan=null;if(this.zoomBox){this.zoomBox.destroy();}
+this.zoomBox=null;OpenLayers.Control.prototype.destroy.apply(this,arguments);},activate:function(){this.dragPan.activate();if(this.zoomWheelEnabled){this.handlers.wheel.activate();}
+this.handlers.click.activate();if(this.zoomBoxEnabled){this.zoomBox.activate();}
+return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){this.zoomBox.deactivate();this.dragPan.deactivate();this.handlers.click.deactivate();this.handlers.wheel.deactivate();return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},draw:function(){if(this.handleRightClicks){this.map.viewPortDiv.oncontextmenu=OpenLayers.Function.False;}
+var clickCallbacks={'dblclick':this.defaultDblClick,'dblrightclick':this.defaultDblRightClick};var clickOptions={'double':true,'stopDouble':true};this.handlers.click=new OpenLayers.Handler.Click(this,clickCallbacks,clickOptions);this.dragPan=new OpenLayers.Control.DragPan(OpenLayers.Util.extend({map:this.map,documentDrag:this.documentDrag},this.dragPanOptions));this.zoomBox=new OpenLayers.Control.ZoomBox({map:this.map,keyMask:this.zoomBoxKeyMask});this.dragPan.draw();this.zoomBox.draw();this.handlers.wheel=new OpenLayers.Handler.MouseWheel(this,{"up":this.wheelUp,"down":this.wheelDown},this.mouseWheelOptions);},defaultDblClick:function(evt){var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom+1);},defaultDblRightClick:function(evt){var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom-1);},wheelChange:function(evt,deltaZ){var currentZoom=this.map.getZoom();var newZoom=this.map.getZoom()+Math.round(deltaZ);newZoom=Math.max(newZoom,0);newZoom=Math.min(newZoom,this.map.getNumZoomLevels());if(newZoom===currentZoom){return;}
+var size=this.map.getSize();var deltaX=size.w/2-evt.xy.x;var deltaY=evt.xy.y-size.h/2;var newRes=this.map.baseLayer.getResolutionForZoom(newZoom);var zoomPoint=this.map.getLonLatFromPixel(evt.xy);var newCenter=new OpenLayers.LonLat(zoomPoint.lon+deltaX*newRes,zoomPoint.lat+deltaY*newRes);this.map.setCenter(newCenter,newZoom);},wheelUp:function(evt,delta){this.wheelChange(evt,delta||1);},wheelDown:function(evt,delta){this.wheelChange(evt,delta||-1);},disableZoomBox:function(){this.zoomBoxEnabled=false;this.zoomBox.deactivate();},enableZoomBox:function(){this.zoomBoxEnabled=true;if(this.active){this.zoomBox.activate();}},disableZoomWheel:function(){this.zoomWheelEnabled=false;this.handlers.wheel.deactivate();},enableZoomWheel:function(){this.zoomWheelEnabled=true;if(this.active){this.handlers.wheel.activate();}},CLASS_NAME:"OpenLayers.Control.Navigation"});OpenLayers.Filter=OpenLayers.Class({initialize:function(options){OpenLayers.Util.extend(this,options);},destroy:function(){},evaluate:function(context){return true;},clone:function(){return null;},CLASS_NAME:"OpenLayers.Filter"});OpenLayers.Format.WMC.v1_0_0=OpenLayers.Class(OpenLayers.Format.WMC.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/context http://schemas.opengis.net/context/1.0.0/context.xsd",initialize:function(options){OpenLayers.Format.WMC.v1.prototype.initialize.apply(this,[options]);},write_wmc_Layer:function(context){var node=OpenLayers.Format.WMC.v1.prototype.write_wmc_Layer.apply(this,[context]);node.appendChild(this.write_wmc_FormatList(context));node.appendChild(this.write_wmc_StyleList(context));node.appendChild(this.write_wmc_LayerExtension(context));},CLASS_NAME:"OpenLayers.Format.WMC.v1_0_0"});OpenLayers.Format.WMC.v1_1_0=OpenLayers.Class(OpenLayers.Format.WMC.v1,{VERSION:"1.1.0",schemaLocation:"http://www.opengis.net/context http://schemas.opengis.net/context/1.1.0/context.xsd",initialize:function(options){OpenLayers.Format.WMC.v1.prototype.initialize.apply(this,[options]);},read_sld_MinScaleDenominator:function(layerContext,node){var minScaleDenominator=parseFloat(this.getChildValue(node));if(minScaleDenominator>0){layerContext.maxScale=minScaleDenominator;}},read_sld_MaxScaleDenominator:function(layerContext,node){layerContext.minScale=parseFloat(this.getChildValue(node));},write_wmc_Layer:function(context){var node=OpenLayers.Format.WMC.v1.prototype.write_wmc_Layer.apply(this,[context]);if(context.maxScale){var minSD=this.createElementNS(this.namespaces.sld,"sld:MinScaleDenominator");minSD.appendChild(this.createTextNode(context.maxScale.toPrecision(16)));node.appendChild(minSD);}
+if(context.minScale){var maxSD=this.createElementNS(this.namespaces.sld,"sld:MaxScaleDenominator");maxSD.appendChild(this.createTextNode(context.minScale.toPrecision(16)));node.appendChild(maxSD);}
+node.appendChild(this.write_wmc_FormatList(context));node.appendChild(this.write_wmc_StyleList(context));node.appendChild(this.write_wmc_LayerExtension(context));return node;},CLASS_NAME:"OpenLayers.Format.WMC.v1_1_0"});OpenLayers.Format.WMSCapabilities.v1_1_0=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_1,{version:"1.1.0",initialize:function(options){OpenLayers.Format.WMSCapabilities.v1_1.prototype.initialize.apply(this,[options]);},readers:{"wms":OpenLayers.Util.applyDefaults({"SRS":function(node,obj){var srs=this.getChildValue(node);var values=srs.split(/ +/);for(var i=0,len=values.length;i<len;i++){obj.srs[values[i]]=true;}}},OpenLayers.Format.WMSCapabilities.v1_1.prototype.readers["wms"])},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1_0"});OpenLayers.Format.WMSCapabilities.v1_1_1=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_1,{version:"1.1.1",initialize:function(options){OpenLayers.Format.WMSCapabilities.v1_1.prototype.initialize.apply(this,[options]);},readers:{"wms":OpenLayers.Util.applyDefaults({"SRS":function(node,obj){obj.srs[this.getChildValue(node)]=true;}},OpenLayers.Format.WMSCapabilities.v1_1.prototype.readers["wms"])},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1_1"});OpenLayers.Format.WMSCapabilities.v1_3_0=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_3,{version:"1.3.0",CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_3_0"});OpenLayers.Geometry=OpenLayers.Class({id:null,parent:null,bounds:null,initialize:function(){this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){this.id=null;this.bounds=null;},clone:function(){return new OpenLayers.Geometry();},setBounds:function(bounds){if(bounds){this.bounds=bounds.clone();}},clearBounds:function(){this.bounds=null;if(this.parent){this.parent.clearBounds();}},extendBounds:function(newBounds){var bounds=this.getBounds();if(!bounds){this.setBounds(newBounds);}else{this.bounds.extend(newBounds);}},getBounds:function(){if(this.bounds==null){this.calculateBounds();}
+return this.bounds;},calculateBounds:function(){},distanceTo:function(geometry,options){},getVertices:function(nodes){},atPoint:function(lonlat,toleranceLon,toleranceLat){var atPoint=false;var bounds=this.getBounds();if((bounds!=null)&&(lonlat!=null)){var dX=(toleranceLon!=null)?toleranceLon:0;var dY=(toleranceLat!=null)?toleranceLat:0;var toleranceBounds=new OpenLayers.Bounds(this.bounds.left-dX,this.bounds.bottom-dY,this.bounds.right+dX,this.bounds.top+dY);atPoint=toleranceBounds.containsLonLat(lonlat);}
+return atPoint;},getLength:function(){return 0.0;},getArea:function(){return 0.0;},getCentroid:function(){return null;},toString:function(){return OpenLayers.Format.WKT.prototype.write(new OpenLayers.Feature.Vector(this));},CLASS_NAME:"OpenLayers.Geometry"});OpenLayers.Geometry.fromWKT=function(wkt){var format=arguments.callee.format;if(!format){format=new OpenLayers.Format.WKT();arguments.callee.format=format;}
+var geom;var result=format.read(wkt);if(result instanceof OpenLayers.Feature.Vector){geom=result.geometry;}else if(result instanceof Array){var len=result.length;var components=new Array(len);for(var i=0;i<len;++i){components[i]=result[i].geometry;}
+geom=new OpenLayers.Geometry.Collection(components);}
+return geom;};OpenLayers.Geometry.segmentsIntersect=function(seg1,seg2,options){var point=options&&options.point;var tolerance=options&&options.tolerance;var intersection=false;var x11_21=seg1.x1-seg2.x1;var y11_21=seg1.y1-seg2.y1;var x12_11=seg1.x2-seg1.x1;var y12_11=seg1.y2-seg1.y1;var y22_21=seg2.y2-seg2.y1;var x22_21=seg2.x2-seg2.x1;var d=(y22_21*x12_11)-(x22_21*y12_11);var n1=(x22_21*y11_21)-(y22_21*x11_21);var n2=(x12_11*y11_21)-(y12_11*x11_21);if(d==0){if(n1==0&&n2==0){intersection=true;}}else{var along1=n1/d;var along2=n2/d;if(along1>=0&&along1<=1&&along2>=0&&along2<=1){if(!point){intersection=true;}else{var x=seg1.x1+(along1*x12_11);var y=seg1.y1+(along1*y12_11);intersection=new OpenLayers.Geometry.Point(x,y);}}}
+if(tolerance){var dist;if(intersection){if(point){var segs=[seg1,seg2];var seg,x,y;outer:for(var i=0;i<2;++i){seg=segs[i];for(var j=1;j<3;++j){x=seg["x"+j];y=seg["y"+j];dist=Math.sqrt(Math.pow(x-intersection.x,2)+
+Math.pow(y-intersection.y,2));if(dist<tolerance){intersection.x=x;intersection.y=y;break outer;}}}}}else{var segs=[seg1,seg2];var source,target,x,y,p,result;outer:for(var i=0;i<2;++i){source=segs[i];target=segs[(i+1)%2];for(var j=1;j<3;++j){p={x:source["x"+j],y:source["y"+j]};result=OpenLayers.Geometry.distanceToSegment(p,target);if(result.distance<tolerance){if(point){intersection=new OpenLayers.Geometry.Point(p.x,p.y);}else{intersection=true;}
+break outer;}}}}}
+return intersection;};OpenLayers.Geometry.distanceToSegment=function(point,segment){var x0=point.x;var y0=point.y;var x1=segment.x1;var y1=segment.y1;var x2=segment.x2;var y2=segment.y2;var dx=x2-x1;var dy=y2-y1;var along=((dx*(x0-x1))+(dy*(y0-y1)))/(Math.pow(dx,2)+Math.pow(dy,2));var x,y;if(along<=0.0){x=x1;y=y1;}else if(along>=1.0){x=x2;y=y2;}else{x=x1+along*dx;y=y1+along*dy;}
+return{distance:Math.sqrt(Math.pow(x-x0,2)+Math.pow(y-y0,2)),x:x,y:y};};OpenLayers.Layer.ArcGIS93Rest=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{format:"png"},isBaseLayer:true,initialize:function(name,url,params,options){var newArguments=[];params=OpenLayers.Util.upperCaseObject(params);newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);OpenLayers.Util.applyDefaults(this.params,OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS));if(this.params.TRANSPARENT&&this.params.TRANSPARENT.toString().toLowerCase()=="true"){if((options==null)||(!options.isBaseLayer)){this.isBaseLayer=false;}
+if(this.params.FORMAT=="jpg"){this.params.FORMAT=OpenLayers.Util.alphaHack()?"gif":"png";}}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.ArcGIS93Rest(this.name,this.url,this.params,this.getOptions());}
+obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var projWords=this.projection.getCode().split(":");var srid=projWords[projWords.length-1];var imageSize=this.getImageSize();var newParams={'BBOX':bounds.toBBOX(),'SIZE':imageSize.w+","+imageSize.h,'F':"image",'BBOXSR':srid,'IMAGESR':srid};if(this.layerDefs){var layerDefStrList=[];var layerID;for(layerID in this.layerDefs){if(this.layerDefs.hasOwnProperty(layerID)){if(this.layerDefs[layerID]){layerDefStrList.push(layerID);layerDefStrList.push(":");layerDefStrList.push(this.layerDefs[layerID]);layerDefStrList.push(";");}}}
+if(layerDefStrList.length>0){newParams['LAYERDEFS']=layerDefStrList.join("");}}
+var requestString=this.getFullRequestString(newParams);return requestString;},setLayerFilter:function(id,queryDef){if(!this.layerDefs){this.layerDefs={};}
+if(queryDef){this.layerDefs[id]=queryDef;}else{delete this.layerDefs[id];}},clearLayerFilter:function(id){if(id){delete this.layerDefs[id];}else{delete this.layerDefs;}},mergeNewParams:function(newParams){var upperParams=OpenLayers.Util.upperCaseObject(newParams);var newArguments=[upperParams];return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,newArguments);},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.ArcGIS93Rest"});OpenLayers.Layer.Google.v3={DEFAULTS:{maxExtent:new OpenLayers.Bounds(-128*156543.0339,-128*156543.0339,128*156543.0339,128*156543.0339),sphericalMercator:true,maxResolution:156543.0339,units:"m",projection:"EPSG:900913"},loadMapObject:function(){if(!this.type){this.type=google.maps.MapTypeId.ROADMAP;}
+var mapObject;var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){mapObject=cache.mapObject;++cache.count;}else{var container=this.map.viewPortDiv;var div=document.createElement("div");div.id=this.map.id+"_GMapContainer";div.style.position="absolute";div.style.width="100%";div.style.height="100%";container.appendChild(div);var center=this.map.getCenter();mapObject=new google.maps.Map(div,{center:center?new google.maps.LatLng(center.lat,center.lon):new google.maps.LatLng(0,0),zoom:this.map.getZoom()||0,mapTypeId:this.type,disableDefaultUI:true,keyboardShortcuts:false,draggable:false,disableDoubleClickZoom:true,scrollwheel:false});cache={mapObject:mapObject,count:1};OpenLayers.Layer.Google.cache[this.map.id]=cache;this.repositionListener=google.maps.event.addListenerOnce(mapObject,"center_changed",OpenLayers.Function.bind(this.repositionMapElements,this));}
+this.mapObject=mapObject;this.setGMapVisibility(this.visibility);},repositionMapElements:function(){google.maps.event.trigger(this.mapObject,"resize");var div=this.mapObject.getDiv().firstChild;if(!div||div.childNodes.length<3){this.repositionTimer=window.setTimeout(OpenLayers.Function.bind(this.repositionMapElements,this),250);return false;}
+var cache=OpenLayers.Layer.Google.cache[this.map.id];var container=this.map.viewPortDiv;var termsOfUse=div.lastChild;container.appendChild(termsOfUse);termsOfUse.style.zIndex="1100";termsOfUse.style.bottom="";termsOfUse.className="olLayerGoogleCopyright olLayerGoogleV3";termsOfUse.style.display="";cache.termsOfUse=termsOfUse;var poweredBy=div.lastChild;container.appendChild(poweredBy);poweredBy.style.zIndex="1100";poweredBy.style.bottom="";poweredBy.className="olLayerGooglePoweredBy olLayerGoogleV3 gmnoprint";poweredBy.style.display="";cache.poweredBy=poweredBy;this.setGMapVisibility(this.visibility);},onMapResize:function(){if(this.visibility){google.maps.event.trigger(this.mapObject,"resize");}else{if(!this._resized){var layer=this;google.maps.event.addListenerOnce(this.mapObject,"tilesloaded",function(){delete layer._resized;google.maps.event.trigger(layer.mapObject,"resize");layer.moveTo(layer.map.getCenter(),layer.map.getZoom());});}
+this._resized=true;}},setGMapVisibility:function(visible){var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){var type=this.type;var layers=this.map.layers;var layer;for(var i=layers.length-1;i>=0;--i){layer=layers[i];if(layer instanceof OpenLayers.Layer.Google&&layer.visibility===true&&layer.inRange===true){type=layer.type;visible=true;break;}}
+var container=this.mapObject.getDiv();if(visible===true){this.mapObject.setMapTypeId(type);container.style.left="";if(cache.termsOfUse&&cache.termsOfUse.style){cache.termsOfUse.style.left="";cache.termsOfUse.style.display="";cache.poweredBy.style.display="";}
+cache.displayed=this.id;}else{delete cache.displayed;container.style.left="-9999px";if(cache.termsOfUse&&cache.termsOfUse.style){cache.termsOfUse.style.display="none";cache.termsOfUse.style.left="-9999px";cache.poweredBy.style.display="none";}}}},getMapContainer:function(){return this.mapObject.getDiv();},getMapObjectBoundsFromOLBounds:function(olBounds){var moBounds=null;if(olBounds!=null){var sw=this.sphericalMercator?this.inverseMercator(olBounds.bottom,olBounds.left):new OpenLayers.LonLat(olBounds.bottom,olBounds.left);var ne=this.sphericalMercator?this.inverseMercator(olBounds.top,olBounds.right):new OpenLayers.LonLat(olBounds.top,olBounds.right);moBounds=new google.maps.LatLngBounds(new google.maps.LatLng(sw.lat,sw.lon),new google.maps.LatLng(ne.lat,ne.lon));}
+return moBounds;},getMapObjectLonLatFromMapObjectPixel:function(moPixel){var size=this.map.getSize();var lon=this.getLongitudeFromMapObjectLonLat(this.mapObject.center);var lat=this.getLatitudeFromMapObjectLonLat(this.mapObject.center);var res=this.map.getResolution();var delta_x=moPixel.x-(size.w/2);var delta_y=moPixel.y-(size.h/2);var lonlat=new OpenLayers.LonLat(lon+delta_x*res,lat-delta_y*res);if(this.wrapDateLine){lonlat=lonlat.wrapDateLine(this.maxExtent);}
+return this.getMapObjectLonLatFromLonLat(lonlat.lon,lonlat.lat);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){var lon=this.getLongitudeFromMapObjectLonLat(moLonLat);var lat=this.getLatitudeFromMapObjectLonLat(moLonLat);var res=this.map.getResolution();var extent=this.map.getExtent();var px=new OpenLayers.Pixel((1/res*(lon-extent.left)),(1/res*(extent.top-lat)));return this.getMapObjectPixelFromXY(px.x,px.y);},setMapObjectCenter:function(center,zoom){this.mapObject.setOptions({center:center,zoom:zoom});},getMapObjectZoomFromMapObjectBounds:function(moBounds){return this.mapObject.getBoundsZoomLevel(moBounds);},getMapObjectLonLatFromLonLat:function(lon,lat){var gLatLng;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);gLatLng=new google.maps.LatLng(lonlat.lat,lonlat.lon);}else{gLatLng=new google.maps.LatLng(lat,lon);}
+return gLatLng;},getMapObjectPixelFromXY:function(x,y){return new google.maps.Point(x,y);},destroy:function(){if(this.repositionListener){google.maps.event.removeListener(this.repositionListener);}
+if(this.repositionTimer){window.clearTimeout(this.repositionTimer);}
+OpenLayers.Layer.Google.prototype.destroy.apply(this,arguments);}};OpenLayers.Layer.KaMap=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,units:null,resolution:OpenLayers.DOTS_PER_INCH,DEFAULT_PARAMS:{i:'jpeg',map:''},initialize:function(name,url,params,options){var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS);},getURL:function(bounds){bounds=this.adjustBounds(bounds);var mapRes=this.map.getResolution();var scale=Math.round((this.map.getScale()*10000))/10000;var pX=Math.round(bounds.left/mapRes);var pY=-Math.round(bounds.top/mapRes);return this.getFullRequestString({t:pY,l:pX,s:scale});},addTile:function(bounds,position){var url=this.getURL(bounds);return new OpenLayers.Tile.Image(this,position,bounds,url,this.tileSize);},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=tilecol*tilelon;var offsetlat=bounds.top;var tilerow=Math.ceil(offsetlat/tilelat)+this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=-(tilerowremain+1)*this.tileSize.h;var tileoffsetlat=tilerow*tilelat;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.KaMap(this.name,this.url,this.params,this.getOptions());}
+obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);if(this.tileSize!=null){obj.tileSize=this.tileSize.clone();}
+obj.grid=[];return obj;},getTileBounds:function(viewPortPx){var resolution=this.getResolution();var tileMapWidth=resolution*this.tileSize.w;var tileMapHeight=resolution*this.tileSize.h;var mapPoint=this.getLonLatFromViewPortPx(viewPortPx);var tileLeft=tileMapWidth*Math.floor(mapPoint.lon/tileMapWidth);var tileBottom=tileMapHeight*Math.floor(mapPoint.lat/tileMapHeight);return new OpenLayers.Bounds(tileLeft,tileBottom,tileLeft+tileMapWidth,tileBottom+tileMapHeight);},CLASS_NAME:"OpenLayers.Layer.KaMap"});OpenLayers.Layer.MapGuide=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,useHttpTile:false,singleTile:false,useOverlay:false,useAsyncOverlay:true,TILE_PARAMS:{operation:'GETTILEIMAGE',version:'1.2.0'},SINGLE_TILE_PARAMS:{operation:'GETMAPIMAGE',format:'PNG',locale:'en',clip:'1',version:'1.0.0'},OVERLAY_PARAMS:{operation:'GETDYNAMICMAPOVERLAYIMAGE',format:'PNG',locale:'en',clip:'1',version:'2.0.0'},FOLDER_PARAMS:{tileColumnsPerFolder:30,tileRowsPerFolder:30,format:'png',querystring:null},defaultSize:new OpenLayers.Size(300,300),initialize:function(name,url,params,options){OpenLayers.Layer.Grid.prototype.initialize.apply(this,arguments);if(options==null||options.isBaseLayer==null){this.isBaseLayer=((this.transparent!="true")&&(this.transparent!=true));}
+if(options&&options.useOverlay!=null){this.useOverlay=options.useOverlay;}
+if(this.singleTile){if(this.useOverlay){OpenLayers.Util.applyDefaults(this.params,this.OVERLAY_PARAMS);if(!this.useAsyncOverlay){this.params.version="1.0.0";}}else{OpenLayers.Util.applyDefaults(this.params,this.SINGLE_TILE_PARAMS);}}else{if(this.useHttpTile){OpenLayers.Util.applyDefaults(this.params,this.FOLDER_PARAMS);}else{OpenLayers.Util.applyDefaults(this.params,this.TILE_PARAMS);}
+this.setTileSize(this.defaultSize);}},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.MapGuide(this.name,this.url,this.params,this.getOptions());}
+obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},getURL:function(bounds){var url;var center=bounds.getCenterLonLat();var mapSize=this.map.getSize();if(this.singleTile){var params={setdisplaydpi:OpenLayers.DOTS_PER_INCH,setdisplayheight:mapSize.h*this.ratio,setdisplaywidth:mapSize.w*this.ratio,setviewcenterx:center.lon,setviewcentery:center.lat,setviewscale:this.map.getScale()};if(this.useOverlay&&!this.useAsyncOverlay){var getVisParams={};getVisParams=OpenLayers.Util.extend(getVisParams,params);getVisParams.operation="GETVISIBLEMAPEXTENT";getVisParams.version="1.0.0";getVisParams.session=this.params.session;getVisParams.mapName=this.params.mapName;getVisParams.format='text/xml';url=this.getFullRequestString(getVisParams);OpenLayers.Request.GET({url:url,async:false});}
+url=this.getFullRequestString(params);}else{var currentRes=this.map.getResolution();var colidx=Math.floor((bounds.left-this.maxExtent.left)/currentRes);colidx=Math.round(colidx/this.tileSize.w);var rowidx=Math.floor((this.maxExtent.top-bounds.top)/currentRes);rowidx=Math.round(rowidx/this.tileSize.h);if(this.useHttpTile){url=this.getImageFilePath({tilecol:colidx,tilerow:rowidx,scaleindex:this.resolutions.length-this.map.zoom-1});}else{url=this.getFullRequestString({tilecol:colidx,tilerow:rowidx,scaleindex:this.resolutions.length-this.map.zoom-1});}}
+return url;},getFullRequestString:function(newParams,altUrl){var url=(altUrl==null)?this.url:altUrl;if(typeof url=="object"){url=url[Math.floor(Math.random()*url.length)];}
+var requestString=url;var allParams=OpenLayers.Util.extend({},this.params);allParams=OpenLayers.Util.extend(allParams,newParams);var urlParams=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));for(var key in allParams){if(key.toUpperCase()in urlParams){delete allParams[key];}}
+var paramsString=OpenLayers.Util.getParameterString(allParams);paramsString=paramsString.replace(/,/g,"+");if(paramsString!=""){var lastServerChar=url.charAt(url.length-1);if((lastServerChar=="&")||(lastServerChar=="?")){requestString+=paramsString;}else{if(url.indexOf('?')==-1){requestString+='?'+paramsString;}else{requestString+='&'+paramsString;}}}
+return requestString;},getImageFilePath:function(newParams,altUrl){var url=(altUrl==null)?this.url:altUrl;if(typeof url=="object"){url=url[Math.floor(Math.random()*url.length)];}
+var requestString=url;var tileRowGroup="";var tileColGroup="";if(newParams.tilerow<0){tileRowGroup='-';}
+if(newParams.tilerow==0){tileRowGroup+='0';}else{tileRowGroup+=Math.floor(Math.abs(newParams.tilerow/this.params.tileRowsPerFolder))*this.params.tileRowsPerFolder;}
+if(newParams.tilecol<0){tileColGroup='-';}
+if(newParams.tilecol==0){tileColGroup+='0';}else{tileColGroup+=Math.floor(Math.abs(newParams.tilecol/this.params.tileColumnsPerFolder))*this.params.tileColumnsPerFolder;}
+var tilePath='/S'+Math.floor(newParams.scaleindex)
++'/'+this.params.basemaplayergroupname
++'/R'+tileRowGroup
++'/C'+tileColGroup
++'/'+(newParams.tilerow%this.params.tileRowsPerFolder)
++'_'+(newParams.tilecol%this.params.tileColumnsPerFolder)
++'.'+this.params.format;if(this.params.querystring){tilePath+="?"+this.params.querystring;}
+requestString+=tilePath;return requestString;},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left-extent.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=extent.left+tilecol*tilelon;var offsetlat=extent.top-bounds.top+tilelat;var tilerow=Math.floor(offsetlat/tilelat)-this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=tilerowremain*this.tileSize.h;var tileoffsetlat=extent.top-tilelat*tilerow;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},CLASS_NAME:"OpenLayers.Layer.MapGuide"});OpenLayers.Layer.MapServer=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{mode:"map",map_imagetype:"png"},initialize:function(name,url,params,options){var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS);if(options==null||options.isBaseLayer==null){this.isBaseLayer=((this.params.transparent!="true")&&(this.params.transparent!=true));}},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.MapServer(this.name,this.url,this.params,this.getOptions());}
+obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},getURL:function(bounds){bounds=this.adjustBounds(bounds);var extent=[bounds.left,bounds.bottom,bounds.right,bounds.top];var imageSize=this.getImageSize();var url=this.getFullRequestString({mapext:extent,imgext:extent,map_size:[imageSize.w,imageSize.h],imgx:imageSize.w/2,imgy:imageSize.h/2,imgxy:[imageSize.w,imageSize.h]});return url;},getFullRequestString:function(newParams,altUrl){var url=(altUrl==null)?this.url:altUrl;var allParams=OpenLayers.Util.extend({},this.params);allParams=OpenLayers.Util.extend(allParams,newParams);var paramsString=OpenLayers.Util.getParameterString(allParams);if(url instanceof Array){url=this.selectUrl(paramsString,url);}
+var urlParams=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));for(var key in allParams){if(key.toUpperCase()in urlParams){delete allParams[key];}}
+paramsString=OpenLayers.Util.getParameterString(allParams);var requestString=url;paramsString=paramsString.replace(/,/g,"+");if(paramsString!=""){var lastServerChar=url.charAt(url.length-1);if((lastServerChar=="&")||(lastServerChar=="?")){requestString+=paramsString;}else{if(url.indexOf('?')==-1){requestString+='?'+paramsString;}else{requestString+='&'+paramsString;}}}
+return requestString;},CLASS_NAME:"OpenLayers.Layer.MapServer"});OpenLayers.Layer.TMS=OpenLayers.Class(OpenLayers.Layer.Grid,{serviceVersion:"1.0.0",isBaseLayer:true,tileOrigin:null,serverResolutions:null,zoomOffset:0,initialize:function(name,url,options){var newArguments=[];newArguments.push(name,url,{},options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.TMS(this.name,this.url,this.getOptions());}
+obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var res=this.map.getResolution();var x=Math.round((bounds.left-this.tileOrigin.lon)/(res*this.tileSize.w));var y=Math.round((bounds.bottom-this.tileOrigin.lat)/(res*this.tileSize.h));var z=this.serverResolutions!=null?OpenLayers.Util.indexOf(this.serverResolutions,res):this.map.getZoom()+this.zoomOffset;var path=this.serviceVersion+"/"+this.layername+"/"+z+"/"+x+"/"+y+"."+this.type;var url=this.url;if(url instanceof Array){url=this.selectUrl(path,url);}
+return url+path;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},setMap:function(map){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);if(!this.tileOrigin){this.tileOrigin=new OpenLayers.LonLat(this.map.maxExtent.left,this.map.maxExtent.bottom);}},CLASS_NAME:"OpenLayers.Layer.TMS"});OpenLayers.Layer.TileCache=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,format:'image/png',serverResolutions:null,initialize:function(name,url,layername,options){this.layername=layername;OpenLayers.Layer.Grid.prototype.initialize.apply(this,[name,url,{},options]);this.extension=this.format.split('/')[1].toLowerCase();this.extension=(this.extension=='jpg')?'jpeg':this.extension;},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.TileCache(this.name,this.url,this.layername,this.getOptions());}
+obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){var res=this.map.getResolution();var bbox=this.maxExtent;var size=this.tileSize;var tileX=Math.round((bounds.left-bbox.left)/(res*size.w));var tileY=Math.round((bounds.bottom-bbox.bottom)/(res*size.h));var tileZ=this.serverResolutions!=null?OpenLayers.Util.indexOf(this.serverResolutions,res):this.map.getZoom();function zeroPad(number,length){number=String(number);var zeros=[];for(var i=0;i<length;++i){zeros.push('0');}
+return zeros.join('').substring(0,length-number.length)+number;}
+var components=[this.layername,zeroPad(tileZ,2),zeroPad(parseInt(tileX/1000000),3),zeroPad((parseInt(tileX/1000)%1000),3),zeroPad((parseInt(tileX)%1000),3),zeroPad(parseInt(tileY/1000000),3),zeroPad((parseInt(tileY/1000)%1000),3),zeroPad((parseInt(tileY)%1000),3)+'.'+this.extension];var path=components.join('/');var url=this.url;if(url instanceof Array){url=this.selectUrl(path,url);}
+url=(url.charAt(url.length-1)=='/')?url:url+'/';return url+path;},addTile:function(bounds,position){var url=this.getURL(bounds);return new OpenLayers.Tile.Image(this,position,bounds,url,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.TileCache"});OpenLayers.Layer.WMS=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{service:"WMS",version:"1.1.1",request:"GetMap",styles:"",exceptions:"application/vnd.ogc.se_inimage",format:"image/jpeg"},reproject:false,isBaseLayer:true,encodeBBOX:false,noMagic:false,yx:{'EPSG:4326':true},initialize:function(name,url,params,options){var newArguments=[];params=OpenLayers.Util.upperCaseObject(params);if(parseFloat(params.VERSION)>=1.3&&!params.EXCEPTIONS){params.EXCEPTIONS="INIMAGE";}
+newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);OpenLayers.Util.applyDefaults(this.params,OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS));if(!this.noMagic&&this.params.TRANSPARENT&&this.params.TRANSPARENT.toString().toLowerCase()=="true"){if((options==null)||(!options.isBaseLayer)){this.isBaseLayer=false;}
+if(this.params.FORMAT=="image/jpeg"){this.params.FORMAT=OpenLayers.Util.alphaHack()?"image/gif":"image/png";}}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WMS(this.name,this.url,this.params,this.getOptions());}
+obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},reverseAxisOrder:function(){return(parseFloat(this.params.VERSION)>=1.3&&!!this.yx[this.map.getProjectionObject().getCode()]);},getURL:function(bounds){bounds=this.adjustBounds(bounds);var imageSize=this.getImageSize();var newParams={};var reverseAxisOrder=this.reverseAxisOrder();newParams.BBOX=this.encodeBBOX?bounds.toBBOX(null,reverseAxisOrder):bounds.toArray(reverseAxisOrder);newParams.WIDTH=imageSize.w;newParams.HEIGHT=imageSize.h;var requestString=this.getFullRequestString(newParams);return requestString;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},mergeNewParams:function(newParams){var upperParams=OpenLayers.Util.upperCaseObject(newParams);var newArguments=[upperParams];return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,newArguments);},getFullRequestString:function(newParams,altUrl){var projectionCode=this.map.getProjection();var value=(projectionCode=="none")?null:projectionCode
+if(parseFloat(this.params.VERSION)>=1.3){this.params.CRS=value;}else{this.params.SRS=value;}
+return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this,arguments);},CLASS_NAME:"OpenLayers.Layer.WMS"});OpenLayers.Layer.WMTS=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,version:"1.0.0",requestEncoding:"KVP",url:null,layer:null,matrixSet:null,style:null,format:"image/jpeg",tileOrigin:null,tileFullExtent:null,formatSuffix:null,matrixIds:null,dimensions:null,params:null,zoomOffset:0,formatSuffixMap:{"image/png":"png","image/png8":"png","image/png24":"png","image/png32":"png","png":"png","image/jpeg":"jpg","image/jpg":"jpg","jpeg":"jpg","jpg":"jpg"},matrix:null,initialize:function(config){var required={url:true,layer:true,style:true,matrixSet:true};for(var prop in required){if(!(prop in config)){throw new Error("Missing property '"+prop+"' in layer configuration.");}}
+config.params=OpenLayers.Util.upperCaseObject(config.params);var args=[config.name,config.url,config.params,config];OpenLayers.Layer.Grid.prototype.initialize.apply(this,args);if(!this.formatSuffix){this.formatSuffix=this.formatSuffixMap[this.format]||this.format.split("/").pop();}
+if(this.matrixIds){var len=this.matrixIds.length;if(len&&typeof this.matrixIds[0]==="string"){var ids=this.matrixIds;this.matrixIds=new Array(len);for(var i=0;i<len;++i){this.matrixIds[i]={identifier:ids[i]};}}}},setMap:function(){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);this.updateMatrixProperties();},updateMatrixProperties:function(){this.matrix=this.getMatrix();if(this.matrix){if(this.matrix.topLeftCorner){this.tileOrigin=this.matrix.topLeftCorner;}
+if(this.matrix.tileWidth&&this.matrix.tileHeight){this.tileSize=new OpenLayers.Size(this.matrix.tileWidth,this.matrix.tileHeight);}
+if(!this.tileOrigin){this.tileOrigin=new OpenLayers.LonLat(this.maxExtent.left,this.maxExtent.top);}
+if(!this.tileFullExtent){this.tileFullExtent=this.maxExtent;}}},moveTo:function(bounds,zoomChanged,dragging){if(zoomChanged||!this.matrix){this.updateMatrixProperties();}
+return OpenLayers.Layer.Grid.prototype.moveTo.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WMTS(this.options);}
+obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getMatrix:function(){var matrix;if(!this.matrixIds||this.matrixIds.length===0){matrix={identifier:this.map.getZoom()+this.zoomOffset};}else{if("scaleDenominator"in this.matrixIds[0]){var denom=OpenLayers.METERS_PER_INCH*OpenLayers.INCHES_PER_UNIT[this.units]*this.map.getResolution()/0.28E-3;var diff=Number.POSITIVE_INFINITY;var delta;for(var i=0,ii=this.matrixIds.length;i<ii;++i){delta=Math.abs(1-(this.matrixIds[i].scaleDenominator/denom));if(delta<diff){diff=delta;matrix=this.matrixIds[i];}}}else{matrix=this.matrixIds[this.map.getZoom()+this.zoomOffset];}}
+return matrix;},getTileInfo:function(loc){var res=this.map.getResolution();var fx=(loc.lon-this.tileOrigin.lon)/(res*this.tileSize.w);var fy=(this.tileOrigin.lat-loc.lat)/(res*this.tileSize.h);var col=Math.floor(fx);var row=Math.floor(fy);return{col:col,row:row,i:Math.floor((fx-col)*this.tileSize.w),j:Math.floor((fy-row)*this.tileSize.h)};},getURL:function(bounds){bounds=this.adjustBounds(bounds);var url="";if(!this.tileFullExtent||this.tileFullExtent.intersectsBounds(bounds)){var center=bounds.getCenterLonLat();var info=this.getTileInfo(center);var matrixId=this.matrix.identifier;if(this.requestEncoding.toUpperCase()==="REST"){var path=this.version+"/"+this.layer+"/"+this.style+"/";if(this.dimensions){for(var i=0;i<this.dimensions.length;i++){if(this.params[this.dimensions[i]]){path=path+this.params[this.dimensions[i]]+"/";}}}
+path=path+this.matrixSet+"/"+this.matrix.identifier+"/"+info.row+"/"+info.col+"."+this.formatSuffix;if(this.url instanceof Array){url=this.selectUrl(path,this.url);}else{url=this.url;}
+if(!url.match(/\/$/)){url=url+"/";}
+url=url+path;}else if(this.requestEncoding.toUpperCase()==="KVP"){var params={SERVICE:"WMTS",REQUEST:"GetTile",VERSION:this.version,LAYER:this.layer,STYLE:this.style,TILEMATRIXSET:this.matrixSet,TILEMATRIX:this.matrix.identifier,TILEROW:info.row,TILECOL:info.col,FORMAT:this.format};url=OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this,[params]);}}
+return url;},mergeNewParams:function(newParams){if(this.requestEncoding.toUpperCase()==="KVP"){return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,[OpenLayers.Util.upperCaseObject(newParams)]);}},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.WMTS"});OpenLayers.Layer.WorldWind=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{},isBaseLayer:true,lzd:null,zoomLevels:null,initialize:function(name,url,lzd,zoomLevels,params,options){this.lzd=lzd;this.zoomLevels=zoomLevels;var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS);},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},getZoom:function(){var zoom=this.map.getZoom();var extent=this.map.getMaxExtent();zoom=zoom-Math.log(this.maxResolution/(this.lzd/512))/Math.log(2);return zoom;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var zoom=this.getZoom();var extent=this.map.getMaxExtent();var deg=this.lzd/Math.pow(2,this.getZoom());var x=Math.floor((bounds.left-extent.left)/deg);var y=Math.floor((bounds.bottom-extent.bottom)/deg);if(this.map.getResolution()<=(this.lzd/512)&&this.getZoom()<=this.zoomLevels){return this.getFullRequestString({L:zoom,X:x,Y:y});}else{return OpenLayers.Util.getImagesLocation()+"blank.gif";}},CLASS_NAME:"OpenLayers.Layer.WorldWind"});OpenLayers.Layer.XYZ=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,sphericalMercator:false,zoomOffset:0,initialize:function(name,url,options){if(options&&options.sphericalMercator||this.sphericalMercator){options=OpenLayers.Util.extend({maxExtent:new OpenLayers.Bounds(-128*156543.0339,-128*156543.0339,128*156543.0339,128*156543.0339),maxResolution:156543.0339,numZoomLevels:19,units:"m",projection:"EPSG:900913"},options);}
+url=url||this.url;name=name||this.name;var newArguments=[name,url,{},options];OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.XYZ(this.name,this.url,this.getOptions());}
+obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){var res=this.map.getResolution();var x=Math.round((bounds.left-this.maxExtent.left)/(res*this.tileSize.w));var y=Math.round((this.maxExtent.top-bounds.top)/(res*this.tileSize.h));var z=this.map.getZoom()+this.zoomOffset;var url=this.url;var s=''+x+y+z;if(url instanceof Array)
+{url=this.selectUrl(s,url);}
+var path=OpenLayers.String.format(url,{'x':x,'y':y,'z':z});return path;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},setMap:function(map){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);if(!this.tileOrigin){this.tileOrigin=new OpenLayers.LonLat(this.maxExtent.left,this.maxExtent.bottom);}},CLASS_NAME:"OpenLayers.Layer.XYZ"});OpenLayers.Layer.OSM=OpenLayers.Class(OpenLayers.Layer.XYZ,{name:"OpenStreetMap",attribution:"Data CC-By-SA by <a href='http://openstreetmap.org/'>OpenStreetMap</a>",sphericalMercator:true,url:'http://tile.openstreetmap.org/${z}/${x}/${y}.png',clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.OSM(this.name,this.url,this.getOptions());}
+obj=OpenLayers.Layer.XYZ.prototype.clone.apply(this,[obj]);return obj;},CLASS_NAME:"OpenLayers.Layer.OSM"});OpenLayers.Layer.Zoomify=OpenLayers.Class(OpenLayers.Layer.Grid,{url:null,size:null,isBaseLayer:true,standardTileSize:256,numberOfTiers:0,tileCountUpToTier:new Array(),tierSizeInTiles:new Array(),tierImageSize:new Array(),initialize:function(name,url,size,options){this.initializeZoomify(size);var newArguments=[];newArguments.push(name,url,size,{},options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);},initializeZoomify:function(size){var imageSize=size.clone()
+var tiles=new OpenLayers.Size(Math.ceil(imageSize.w/this.standardTileSize),Math.ceil(imageSize.h/this.standardTileSize));this.tierSizeInTiles.push(tiles);this.tierImageSize.push(imageSize);while(imageSize.w>this.standardTileSize||imageSize.h>this.standardTileSize){imageSize=new OpenLayers.Size(Math.floor(imageSize.w/2),Math.floor(imageSize.h/2));tiles=new OpenLayers.Size(Math.ceil(imageSize.w/this.standardTileSize),Math.ceil(imageSize.h/this.standardTileSize));this.tierSizeInTiles.push(tiles);this.tierImageSize.push(imageSize);}
+this.tierSizeInTiles.reverse();this.tierImageSize.reverse();this.numberOfTiers=this.tierSizeInTiles.length;this.tileCountUpToTier[0]=0;for(var i=1;i<this.numberOfTiers;i++){this.tileCountUpToTier.push(this.tierSizeInTiles[i-1].w*this.tierSizeInTiles[i-1].h+
+this.tileCountUpToTier[i-1]);}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);this.tileCountUpToTier.length=0
+this.tierSizeInTiles.length=0
+this.tierImageSize.length=0},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Zoomify(this.name,this.url,this.size,this.options);}
+obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var res=this.map.getResolution();var x=Math.round((bounds.left-this.tileOrigin.lon)/(res*this.tileSize.w));var y=Math.round((this.tileOrigin.lat-bounds.top)/(res*this.tileSize.h));var z=this.map.getZoom();var tileIndex=x+y*this.tierSizeInTiles[z].w+this.tileCountUpToTier[z];var path="TileGroup"+Math.floor((tileIndex)/256)+"/"+z+"-"+x+"-"+y+".jpg";var url=this.url;if(url instanceof Array){url=this.selectUrl(path,url);}
+return url+path;},getImageSize:function(){if(arguments.length>0){bounds=this.adjustBounds(arguments[0]);var res=this.map.getResolution();var x=Math.round((bounds.left-this.tileOrigin.lon)/(res*this.tileSize.w));var y=Math.round((this.tileOrigin.lat-bounds.top)/(res*this.tileSize.h));var z=this.map.getZoom();var w=this.standardTileSize;var h=this.standardTileSize;if(x==this.tierSizeInTiles[z].w-1){var w=this.tierImageSize[z].w%this.standardTileSize;};if(y==this.tierSizeInTiles[z].h-1){var h=this.tierImageSize[z].h%this.standardTileSize;};return(new OpenLayers.Size(w,h));}else{return this.tileSize;}},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},setMap:function(map){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);this.tileOrigin=new OpenLayers.LonLat(this.map.maxExtent.left,this.map.maxExtent.top);},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left-extent.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=extent.left+tilecol*tilelon;var offsetlat=extent.top-bounds.top+tilelat;var tilerow=Math.floor(offsetlat/tilelat)-this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=tilerowremain*this.tileSize.h;var tileoffsetlat=extent.top-tilelat*tilerow;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},CLASS_NAME:"OpenLayers.Layer.Zoomify"});OpenLayers.Protocol.SQL.Gears=OpenLayers.Class(OpenLayers.Protocol.SQL,{FID_PREFIX:'__gears_fid__',NULL_GEOMETRY:'__gears_null_geometry__',NULL_FEATURE_STATE:'__gears_null_feature_state__',jsonParser:null,wktParser:null,fidRegExp:null,saveFeatureState:true,typeOfFid:"string",db:null,initialize:function(options){if(!this.supported()){return;}
+OpenLayers.Protocol.SQL.prototype.initialize.apply(this,[options]);this.jsonParser=new OpenLayers.Format.JSON();this.wktParser=new OpenLayers.Format.WKT();this.fidRegExp=new RegExp('^'+this.FID_PREFIX);this.initializeDatabase();},initializeDatabase:function(){this.db=google.gears.factory.create('beta.database');this.db.open(this.databaseName);this.db.execute("CREATE TABLE IF NOT EXISTS "+this.tableName+" (fid TEXT UNIQUE, geometry TEXT, properties TEXT,"+"  state TEXT)");},destroy:function(){this.db.close();this.db=null;this.jsonParser=null;this.wktParser=null;OpenLayers.Protocol.SQL.prototype.destroy.apply(this);},supported:function(){return!!(window.google&&google.gears);},read:function(options){OpenLayers.Protocol.prototype.read.apply(this,arguments);options=OpenLayers.Util.applyDefaults(options,this.options);var feature,features=[];var rs=this.db.execute("SELECT * FROM "+this.tableName);while(rs.isValidRow()){feature=this.unfreezeFeature(rs);if(this.evaluateFilter(feature,options.filter)){if(!options.noFeatureStateReset){feature.state=null;}
+features.push(feature);}
+rs.next();}
+rs.close();var resp=new OpenLayers.Protocol.Response({code:OpenLayers.Protocol.Response.SUCCESS,requestType:"read",features:features});if(options&&options.callback){options.callback.call(options.scope,resp);}
+return resp;},unfreezeFeature:function(row){var feature;var wkt=row.fieldByName('geometry');if(wkt==this.NULL_GEOMETRY){feature=new OpenLayers.Feature.Vector();}else{feature=this.wktParser.read(wkt);}
+feature.attributes=this.jsonParser.read(row.fieldByName('properties'));feature.fid=this.extractFidFromField(row.fieldByName('fid'));var state=row.fieldByName('state');if(state==this.NULL_FEATURE_STATE){state=null;}
+feature.state=state;return feature;},extractFidFromField:function(field){if(!field.match(this.fidRegExp)&&this.typeOfFid=="number"){field=parseFloat(field);}
+return field;},create:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=this.createOrUpdate(features);resp.requestType="create";if(options&&options.callback){options.callback.call(options.scope,resp);}
+return resp;},update:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=this.createOrUpdate(features);resp.requestType="update";if(options&&options.callback){options.callback.call(options.scope,resp);}
+return resp;},createOrUpdate:function(features){if(!(features instanceof Array)){features=[features];}
+var i,len=features.length,feature;var insertedFeatures=new Array(len);for(i=0;i<len;i++){feature=features[i];var params=this.freezeFeature(feature);this.db.execute("REPLACE INTO "+this.tableName+" (fid, geometry, properties, state)"+" VALUES (?, ?, ?, ?)",params);var clone=feature.clone();clone.fid=this.extractFidFromField(params[0]);insertedFeatures[i]=clone;}
+return new OpenLayers.Protocol.Response({code:OpenLayers.Protocol.Response.SUCCESS,features:insertedFeatures,reqFeatures:features});},freezeFeature:function(feature){feature.fid=feature.fid!=null?""+feature.fid:OpenLayers.Util.createUniqueID(this.FID_PREFIX);var geometry=feature.geometry!=null?feature.geometry.toString():this.NULL_GEOMETRY;var properties=this.jsonParser.write(feature.attributes);var state=this.getFeatureStateForFreeze(feature);return[feature.fid,geometry,properties,state];},getFeatureStateForFreeze:function(feature){var state;if(!this.saveFeatureState){state=this.NULL_FEATURE_STATE;}else if(this.createdOffline(feature)){state=OpenLayers.State.INSERT;}else{state=feature.state;}
+return state;},"delete":function(features,options){if(!(features instanceof Array)){features=[features];}
+options=OpenLayers.Util.applyDefaults(options,this.options);var i,len,feature;for(i=0,len=features.length;i<len;i++){feature=features[i];if(this.saveFeatureState&&!this.createdOffline(feature)){var toDelete=feature.clone();toDelete.fid=feature.fid;if(toDelete.geometry){toDelete.geometry.destroy();toDelete.geometry=null;}
+toDelete.state=feature.state;this.createOrUpdate(toDelete);}else{this.db.execute("DELETE FROM "+this.tableName+" WHERE fid = ?",[feature.fid]);}}
+var resp=new OpenLayers.Protocol.Response({code:OpenLayers.Protocol.Response.SUCCESS,requestType:"delete",reqFeatures:features});if(options&&options.callback){options.callback.call(options.scope,resp);}
+return resp;},createdOffline:function(feature){return(typeof feature.fid=="string"&&!!(feature.fid.match(this.fidRegExp)));},commit:function(features,options){var opt,resp=[],nRequests=0,nResponses=0;function callback(resp){if(++nResponses<nRequests){resp.last=false;}
+this.callUserCallback(options,resp);}
+var feature,toCreate=[],toUpdate=[],toDelete=[];for(var i=features.length-1;i>=0;i--){feature=features[i];switch(feature.state){case OpenLayers.State.INSERT:toCreate.push(feature);break;case OpenLayers.State.UPDATE:toUpdate.push(feature);break;case OpenLayers.State.DELETE:toDelete.push(feature);break;}}
+if(toCreate.length>0){nRequests++;opt=OpenLayers.Util.applyDefaults({"callback":callback,"scope":this},options.create);resp.push(this.create(toCreate,opt));}
+if(toUpdate.length>0){nRequests++;opt=OpenLayers.Util.applyDefaults({"callback":callback,"scope":this},options.update);resp.push(this.update(toUpdate,opt));}
+if(toDelete.length>0){nRequests++;opt=OpenLayers.Util.applyDefaults({"callback":callback,"scope":this},options["delete"]);resp.push(this["delete"](toDelete,opt));}
+return resp;},clear:function(){this.db.execute("DELETE FROM "+this.tableName);},callUserCallback:function(options,resp){var opt=options[resp.requestType];if(opt&&opt.callback){opt.callback.call(opt.scope,resp);}
+if(resp.last&&options.callback){options.callback.call(options.scope);}},CLASS_NAME:"OpenLayers.Protocol.SQL.Gears"});OpenLayers.Rule=OpenLayers.Class({id:null,name:null,title:null,description:null,context:null,filter:null,elseFilter:false,symbolizer:null,symbolizers:null,minScaleDenominator:null,maxScaleDenominator:null,initialize:function(options){this.symbolizer={};OpenLayers.Util.extend(this,options);if(this.symbolizers){delete this.symbolizer;}
+this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){for(var i in this.symbolizer){this.symbolizer[i]=null;}
+this.symbolizer=null;delete this.symbolizers;},evaluate:function(feature){var context=this.getContext(feature);var applies=true;if(this.minScaleDenominator||this.maxScaleDenominator){var scale=feature.layer.map.getScale();}
+if(this.minScaleDenominator){applies=scale>=OpenLayers.Style.createLiteral(this.minScaleDenominator,context);}
+if(applies&&this.maxScaleDenominator){applies=scale<OpenLayers.Style.createLiteral(this.maxScaleDenominator,context);}
+if(applies&&this.filter){if(this.filter.CLASS_NAME=="OpenLayers.Filter.FeatureId"){applies=this.filter.evaluate(feature);}else{applies=this.filter.evaluate(context);}}
+return applies;},getContext:function(feature){var context=this.context;if(!context){context=feature.attributes||feature.data;}
+if(typeof this.context=="function"){context=this.context(feature);}
+return context;},clone:function(){var options=OpenLayers.Util.extend({},this);if(this.symbolizers){var len=this.symbolizers.length;options.symbolizers=new Array(len);for(var i=0;i<len;++i){options.symbolizers[i]=this.symbolizers[i].clone();}}else{options.symbolizer={};var value,type;for(var key in this.symbolizer){value=this.symbolizer[key];type=typeof value;if(type==="object"){options.symbolizer[key]=OpenLayers.Util.extend({},value);}else if(type==="string"){options.symbolizer[key]=value;}}}
+options.filter=this.filter&&this.filter.clone();options.context=this.context&&OpenLayers.Util.extend({},this.context);return new OpenLayers.Rule(options);},CLASS_NAME:"OpenLayers.Rule"});OpenLayers.StyleMap=OpenLayers.Class({styles:null,extendDefault:true,initialize:function(style,options){this.styles={"default":new OpenLayers.Style(OpenLayers.Feature.Vector.style["default"]),"select":new OpenLayers.Style(OpenLayers.Feature.Vector.style["select"]),"temporary":new OpenLayers.Style(OpenLayers.Feature.Vector.style["temporary"]),"delete":new OpenLayers.Style(OpenLayers.Feature.Vector.style["delete"])};if(style instanceof OpenLayers.Style){this.styles["default"]=style;this.styles["select"]=style;this.styles["temporary"]=style;this.styles["delete"]=style;}else if(typeof style=="object"){for(var key in style){if(style[key]instanceof OpenLayers.Style){this.styles[key]=style[key];}else if(typeof style[key]=="object"){this.styles[key]=new OpenLayers.Style(style[key]);}else{this.styles["default"]=new OpenLayers.Style(style);this.styles["select"]=new OpenLayers.Style(style);this.styles["temporary"]=new OpenLayers.Style(style);this.styles["delete"]=new OpenLayers.Style(style);break;}}}
+OpenLayers.Util.extend(this,options);},destroy:function(){for(var key in this.styles){this.styles[key].destroy();}
+this.styles=null;},createSymbolizer:function(feature,intent){if(!feature){feature=new OpenLayers.Feature.Vector();}
+if(!this.styles[intent]){intent="default";}
+feature.renderIntent=intent;var defaultSymbolizer={};if(this.extendDefault&&intent!="default"){defaultSymbolizer=this.styles["default"].createSymbolizer(feature);}
+return OpenLayers.Util.extend(defaultSymbolizer,this.styles[intent].createSymbolizer(feature));},addUniqueValueRules:function(renderIntent,property,symbolizers,context){var rules=[];for(var value in symbolizers){rules.push(new OpenLayers.Rule({symbolizer:symbolizers[value],context:context,filter:new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO,property:property,value:value})}));}
+this.styles[renderIntent].addRules(rules);},CLASS_NAME:"OpenLayers.StyleMap"});OpenLayers.Control.NavToolbar=OpenLayers.Class(OpenLayers.Control.Panel,{initialize:function(options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.Navigation(),new OpenLayers.Control.ZoomBox()]);},draw:function(){var div=OpenLayers.Control.Panel.prototype.draw.apply(this,arguments);this.activateControl(this.controls[0]);return div;},CLASS_NAME:"OpenLayers.Control.NavToolbar"});OpenLayers.Filter.Comparison=OpenLayers.Class(OpenLayers.Filter,{type:null,property:null,value:null,matchCase:true,lowerBoundary:null,upperBoundary:null,initialize:function(options){OpenLayers.Filter.prototype.initialize.apply(this,[options]);},evaluate:function(context){if(context instanceof OpenLayers.Feature.Vector){context=context.attributes;}
+var result=false;var got=context[this.property];switch(this.type){case OpenLayers.Filter.Comparison.EQUAL_TO:var exp=this.value;if(!this.matchCase&&typeof got=="string"&&typeof exp=="string"){result=(got.toUpperCase()==exp.toUpperCase());}else{result=(got==exp);}
+break;case OpenLayers.Filter.Comparison.NOT_EQUAL_TO:var exp=this.value;if(!this.matchCase&&typeof got=="string"&&typeof exp=="string"){result=(got.toUpperCase()!=exp.toUpperCase());}else{result=(got!=exp);}
+break;case OpenLayers.Filter.Comparison.LESS_THAN:result=got<this.value;break;case OpenLayers.Filter.Comparison.GREATER_THAN:result=got>this.value;break;case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO:result=got<=this.value;break;case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO:result=got>=this.value;break;case OpenLayers.Filter.Comparison.BETWEEN:result=(got>=this.lowerBoundary)&&(got<=this.upperBoundary);break;case OpenLayers.Filter.Comparison.LIKE:var regexp=new RegExp(this.value,"gi");result=regexp.test(got);break;}
+return result;},value2regex:function(wildCard,singleChar,escapeChar){if(wildCard=="."){var msg="'.' is an unsupported wildCard character for "+"OpenLayers.Filter.Comparison";OpenLayers.Console.error(msg);return null;}
+wildCard=wildCard?wildCard:"*";singleChar=singleChar?singleChar:".";escapeChar=escapeChar?escapeChar:"!";this.value=this.value.replace(new RegExp("\\"+escapeChar+"(.|$)","g"),"\\$1");this.value=this.value.replace(new RegExp("\\"+singleChar,"g"),".");this.value=this.value.replace(new RegExp("\\"+wildCard,"g"),".*");this.value=this.value.replace(new RegExp("\\\\.\\*","g"),"\\"+wildCard);this.value=this.value.replace(new RegExp("\\\\\\.","g"),"\\"+singleChar);return this.value;},regex2value:function(){var value=this.value;value=value.replace(/!/g,"!!");value=value.replace(/(\\)?\\\./g,function($0,$1){return $1?$0:"!.";});value=value.replace(/(\\)?\\\*/g,function($0,$1){return $1?$0:"!*";});value=value.replace(/\\\\/g,"\\");value=value.replace(/\.\*/g,"*");return value;},clone:function(){return OpenLayers.Util.extend(new OpenLayers.Filter.Comparison(),this);},CLASS_NAME:"OpenLayers.Filter.Comparison"});OpenLayers.Filter.Comparison.EQUAL_TO="==";OpenLayers.Filter.Comparison.NOT_EQUAL_TO="!=";OpenLayers.Filter.Comparison.LESS_THAN="<";OpenLayers.Filter.Comparison.GREATER_THAN=">";OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO="<=";OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO=">=";OpenLayers.Filter.Comparison.BETWEEN="..";OpenLayers.Filter.Comparison.LIKE="~";OpenLayers.Filter.FeatureId=OpenLayers.Class(OpenLayers.Filter,{fids:null,initialize:function(options){this.fids=[];OpenLayers.Filter.prototype.initialize.apply(this,[options]);},evaluate:function(feature){for(var i=0,len=this.fids.length;i<len;i++){var fid=feature.fid||feature.id;if(fid==this.fids[i]){return true;}}
+return false;},clone:function(){var filter=new OpenLayers.Filter.FeatureId();OpenLayers.Util.extend(filter,this);filter.fids=this.fids.slice();return filter;},CLASS_NAME:"OpenLayers.Filter.FeatureId"});OpenLayers.Filter.Logical=OpenLayers.Class(OpenLayers.Filter,{filters:null,type:null,initialize:function(options){this.filters=[];OpenLayers.Filter.prototype.initialize.apply(this,[options]);},destroy:function(){this.filters=null;OpenLayers.Filter.prototype.destroy.apply(this);},evaluate:function(context){switch(this.type){case OpenLayers.Filter.Logical.AND:for(var i=0,len=this.filters.length;i<len;i++){if(this.filters[i].evaluate(context)==false){return false;}}
+return true;case OpenLayers.Filter.Logical.OR:for(var i=0,len=this.filters.length;i<len;i++){if(this.filters[i].evaluate(context)==true){return true;}}
+return false;case OpenLayers.Filter.Logical.NOT:return(!this.filters[0].evaluate(context));}},clone:function(){var filters=[];for(var i=0,len=this.filters.length;i<len;++i){filters.push(this.filters[i].clone());}
+return new OpenLayers.Filter.Logical({type:this.type,filters:filters});},CLASS_NAME:"OpenLayers.Filter.Logical"});OpenLayers.Filter.Logical.AND="&&";OpenLayers.Filter.Logical.OR="||";OpenLayers.Filter.Logical.NOT="!";OpenLayers.Filter.Spatial=OpenLayers.Class(OpenLayers.Filter,{type:null,property:null,value:null,distance:null,distanceUnits:null,initialize:function(options){OpenLayers.Filter.prototype.initialize.apply(this,[options]);},evaluate:function(feature){var intersect=false;switch(this.type){case OpenLayers.Filter.Spatial.BBOX:case OpenLayers.Filter.Spatial.INTERSECTS:if(feature.geometry){var geom=this.value;if(this.value.CLASS_NAME=="OpenLayers.Bounds"){geom=this.value.toGeometry();}
+if(feature.geometry.intersects(geom)){intersect=true;}}
+break;default:OpenLayers.Console.error(OpenLayers.i18n("filterEvaluateNotImplemented"));break;}
+return intersect;},clone:function(){var options=OpenLayers.Util.applyDefaults({value:this.value&&this.value.clone&&this.value.clone()},this);return new OpenLayers.Filter.Spatial(options);},CLASS_NAME:"OpenLayers.Filter.Spatial"});OpenLayers.Filter.Spatial.BBOX="BBOX";OpenLayers.Filter.Spatial.INTERSECTS="INTERSECTS";OpenLayers.Filter.Spatial.DWITHIN="DWITHIN";OpenLayers.Filter.Spatial.WITHIN="WITHIN";OpenLayers.Filter.Spatial.CONTAINS="CONTAINS";OpenLayers.Geometry.Collection=OpenLayers.Class(OpenLayers.Geometry,{components:null,componentTypes:null,initialize:function(components){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);this.components=[];if(components!=null){this.addComponents(components);}},destroy:function(){this.components.length=0;this.components=null;OpenLayers.Geometry.prototype.destroy.apply(this,arguments);},clone:function(){var geometry=eval("new "+this.CLASS_NAME+"()");for(var i=0,len=this.components.length;i<len;i++){geometry.addComponent(this.components[i].clone());}
+OpenLayers.Util.applyDefaults(geometry,this);return geometry;},getComponentsString:function(){var strings=[];for(var i=0,len=this.components.length;i<len;i++){strings.push(this.components[i].toShortString());}
+return strings.join(",");},calculateBounds:function(){this.bounds=null;if(this.components&&this.components.length>0){this.setBounds(this.components[0].getBounds());for(var i=1,len=this.components.length;i<len;i++){this.extendBounds(this.components[i].getBounds());}}},addComponents:function(components){if(!(components instanceof Array)){components=[components];}
+for(var i=0,len=components.length;i<len;i++){this.addComponent(components[i]);}},addComponent:function(component,index){var added=false;if(component){if(this.componentTypes==null||(OpenLayers.Util.indexOf(this.componentTypes,component.CLASS_NAME)>-1)){if(index!=null&&(index<this.components.length)){var components1=this.components.slice(0,index);var components2=this.components.slice(index,this.components.length);components1.push(component);this.components=components1.concat(components2);}else{this.components.push(component);}
+component.parent=this;this.clearBounds();added=true;}}
+return added;},removeComponents:function(components){if(!(components instanceof Array)){components=[components];}
+for(var i=components.length-1;i>=0;--i){this.removeComponent(components[i]);}},removeComponent:function(component){OpenLayers.Util.removeItem(this.components,component);this.clearBounds();},getLength:function(){var length=0.0;for(var i=0,len=this.components.length;i<len;i++){length+=this.components[i].getLength();}
+return length;},getArea:function(){var area=0.0;for(var i=0,len=this.components.length;i<len;i++){area+=this.components[i].getArea();}
+return area;},getGeodesicArea:function(projection){var area=0.0;for(var i=0,len=this.components.length;i<len;i++){area+=this.components[i].getGeodesicArea(projection);}
+return area;},getCentroid:function(weighted){if(!weighted){return this.components.length&&this.components[0].getCentroid();}
+var len=this.components.length;if(!len){return false;}
+var areas=[];var centroids=[];var areaSum=0;var minArea=Number.MAX_VALUE;var component;for(var i=0;i<len;++i){component=this.components[i];var area=component.getArea();var centroid=component.getCentroid(true);if(isNaN(area)||isNaN(centroid.x)||isNaN(centroid.y)){continue;}
+areas.push(area);areaSum+=area;minArea=(area<minArea&&area>0)?area:minArea;centroids.push(centroid);}
+len=areas.length;if(areaSum===0){for(var i=0;i<len;++i){areas[i]=1;}
+areaSum=areas.length;}else{for(var i=0;i<len;++i){areas[i]/=minArea;}
+areaSum/=minArea;}
+var xSum=0,ySum=0,centroid,area;for(var i=0;i<len;++i){centroid=centroids[i];area=areas[i];xSum+=centroid.x*area;ySum+=centroid.y*area;}
+return new OpenLayers.Geometry.Point(xSum/areaSum,ySum/areaSum);},getGeodesicLength:function(projection){var length=0.0;for(var i=0,len=this.components.length;i<len;i++){length+=this.components[i].getGeodesicLength(projection);}
+return length;},move:function(x,y){for(var i=0,len=this.components.length;i<len;i++){this.components[i].move(x,y);}},rotate:function(angle,origin){for(var i=0,len=this.components.length;i<len;++i){this.components[i].rotate(angle,origin);}},resize:function(scale,origin,ratio){for(var i=0;i<this.components.length;++i){this.components[i].resize(scale,origin,ratio);}
+return this;},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var details=edge&&options&&options.details;var result,best,distance;var min=Number.POSITIVE_INFINITY;for(var i=0,len=this.components.length;i<len;++i){result=this.components[i].distanceTo(geometry,options);distance=details?result.distance:result;if(distance<min){min=distance;best=result;if(min==0){break;}}}
+return best;},equals:function(geometry){var equivalent=true;if(!geometry||!geometry.CLASS_NAME||(this.CLASS_NAME!=geometry.CLASS_NAME)){equivalent=false;}else if(!(geometry.components instanceof Array)||(geometry.components.length!=this.components.length)){equivalent=false;}else{for(var i=0,len=this.components.length;i<len;++i){if(!this.components[i].equals(geometry.components[i])){equivalent=false;break;}}}
+return equivalent;},transform:function(source,dest){if(source&&dest){for(var i=0,len=this.components.length;i<len;i++){var component=this.components[i];component.transform(source,dest);}
+this.bounds=null;}
+return this;},intersects:function(geometry){var intersect=false;for(var i=0,len=this.components.length;i<len;++i){intersect=geometry.intersects(this.components[i]);if(intersect){break;}}
+return intersect;},getVertices:function(nodes){var vertices=[];for(var i=0,len=this.components.length;i<len;++i){Array.prototype.push.apply(vertices,this.components[i].getVertices(nodes));}
+return vertices;},CLASS_NAME:"OpenLayers.Geometry.Collection"});OpenLayers.Geometry.Point=OpenLayers.Class(OpenLayers.Geometry,{x:null,y:null,initialize:function(x,y){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);this.x=parseFloat(x);this.y=parseFloat(y);},clone:function(obj){if(obj==null){obj=new OpenLayers.Geometry.Point(this.x,this.y);}
+OpenLayers.Util.applyDefaults(obj,this);return obj;},calculateBounds:function(){this.bounds=new OpenLayers.Bounds(this.x,this.y,this.x,this.y);},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var details=edge&&options&&options.details;var distance,x0,y0,x1,y1,result;if(geometry instanceof OpenLayers.Geometry.Point){x0=this.x;y0=this.y;x1=geometry.x;y1=geometry.y;distance=Math.sqrt(Math.pow(x0-x1,2)+Math.pow(y0-y1,2));result=!details?distance:{x0:x0,y0:y0,x1:x1,y1:y1,distance:distance};}else{result=geometry.distanceTo(this,options);if(details){result={x0:result.x1,y0:result.y1,x1:result.x0,y1:result.y0,distance:result.distance};}}
+return result;},equals:function(geom){var equals=false;if(geom!=null){equals=((this.x==geom.x&&this.y==geom.y)||(isNaN(this.x)&&isNaN(this.y)&&isNaN(geom.x)&&isNaN(geom.y)));}
+return equals;},toShortString:function(){return(this.x+", "+this.y);},move:function(x,y){this.x=this.x+x;this.y=this.y+y;this.clearBounds();},rotate:function(angle,origin){angle*=Math.PI/180;var radius=this.distanceTo(origin);var theta=angle+Math.atan2(this.y-origin.y,this.x-origin.x);this.x=origin.x+(radius*Math.cos(theta));this.y=origin.y+(radius*Math.sin(theta));this.clearBounds();},getCentroid:function(){return new OpenLayers.Geometry.Point(this.x,this.y);},resize:function(scale,origin,ratio){ratio=(ratio==undefined)?1:ratio;this.x=origin.x+(scale*ratio*(this.x-origin.x));this.y=origin.y+(scale*(this.y-origin.y));this.clearBounds();return this;},intersects:function(geometry){var intersect=false;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){intersect=this.equals(geometry);}else{intersect=geometry.intersects(this);}
+return intersect;},transform:function(source,dest){if((source&&dest)){OpenLayers.Projection.transform(this,source,dest);this.bounds=null;}
+return this;},getVertices:function(nodes){return[this];},CLASS_NAME:"OpenLayers.Geometry.Point"});OpenLayers.Geometry.Rectangle=OpenLayers.Class(OpenLayers.Geometry,{x:null,y:null,width:null,height:null,initialize:function(x,y,width,height){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);this.x=x;this.y=y;this.width=width;this.height=height;},calculateBounds:function(){this.bounds=new OpenLayers.Bounds(this.x,this.y,this.x+this.width,this.y+this.height);},getLength:function(){var length=(2*this.width)+(2*this.height);return length;},getArea:function(){var area=this.width*this.height;return area;},CLASS_NAME:"OpenLayers.Geometry.Rectangle"});OpenLayers.Geometry.Surface=OpenLayers.Class(OpenLayers.Geometry,{initialize:function(){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Geometry.Surface"});OpenLayers.Layer.KaMapCache=OpenLayers.Class(OpenLayers.Layer.KaMap,{IMAGE_EXTENSIONS:{'jpeg':'jpg','gif':'gif','png':'png','png8':'png','png24':'png','dithered':'png'},DEFAULT_FORMAT:'jpeg',initialize:function(name,url,params,options){OpenLayers.Layer.KaMap.prototype.initialize.apply(this,arguments);this.extension=this.IMAGE_EXTENSIONS[this.params.i.toLowerCase()||DEFAULT_FORMAT];},getURL:function(bounds){bounds=this.adjustBounds(bounds);var mapRes=this.map.getResolution();var scale=Math.round((this.map.getScale()*10000))/10000;var pX=Math.round(bounds.left/mapRes);var pY=-Math.round(bounds.top/mapRes);var metaX=Math.floor(pX/this.tileSize.w/this.params.metaTileSize.w)*this.tileSize.w*this.params.metaTileSize.w;var metaY=Math.floor(pY/this.tileSize.h/this.params.metaTileSize.h)*this.tileSize.h*this.params.metaTileSize.h;var url=this.url;if(url instanceof Array){url=this.selectUrl(paramsString,url);}
+var components=[url,"/",this.params.map,"/",scale,"/",this.params.g.replace(/\s/g,'_'),"/def/t",metaY,"/l",metaX,"/t",pY,"l",pX,".",this.extension];return components.join("");},CLASS_NAME:"OpenLayers.Layer.KaMapCache"});OpenLayers.Layer.MapServer.Untiled=OpenLayers.Class(OpenLayers.Layer.MapServer,{singleTile:true,initialize:function(name,url,params,options){OpenLayers.Layer.MapServer.prototype.initialize.apply(this,arguments);var msg="The OpenLayers.Layer.MapServer.Untiled class is deprecated and "+"will be removed in 3.0. Instead, you should use the "+"normal OpenLayers.Layer.MapServer class, passing it the option "+"'singleTile' as true.";OpenLayers.Console.warn(msg);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.MapServer.Untiled(this.name,this.url,this.params,this.getOptions());}
+obj=OpenLayers.Layer.MapServer.prototype.clone.apply(this,[obj]);return obj;},CLASS_NAME:"OpenLayers.Layer.MapServer.Untiled"});OpenLayers.Layer.Vector=OpenLayers.Class(OpenLayers.Layer,{EVENT_TYPES:["beforefeatureadded","beforefeaturesadded","featureadded","featuresadded","beforefeatureremoved","beforefeaturesremoved","featureremoved","featuresremoved","beforefeatureselected","featureselected","featureunselected","beforefeaturemodified","featuremodified","afterfeaturemodified","vertexmodified","sketchstarted","sketchmodified","sketchcomplete","refresh"],isBaseLayer:false,isFixed:false,isVector:true,features:null,filter:null,selectedFeatures:null,unrenderedFeatures:null,reportError:true,style:null,styleMap:null,strategies:null,protocol:null,renderers:['SVG','VML','Canvas'],renderer:null,rendererOptions:null,geometryType:null,drawn:false,initialize:function(name,options){this.EVENT_TYPES=OpenLayers.Layer.Vector.prototype.EVENT_TYPES.concat(OpenLayers.Layer.prototype.EVENT_TYPES);OpenLayers.Layer.prototype.initialize.apply(this,arguments);if(!this.renderer||!this.renderer.supported()){this.assignRenderer();}
+if(!this.renderer||!this.renderer.supported()){this.renderer=null;this.displayError();}
+if(!this.styleMap){this.styleMap=new OpenLayers.StyleMap();}
+this.features=[];this.selectedFeatures=[];this.unrenderedFeatures={};if(this.strategies){for(var i=0,len=this.strategies.length;i<len;i++){this.strategies[i].setLayer(this);}}},destroy:function(){if(this.strategies){var strategy,i,len;for(i=0,len=this.strategies.length;i<len;i++){strategy=this.strategies[i];if(strategy.autoDestroy){strategy.destroy();}}
+this.strategies=null;}
+if(this.protocol){if(this.protocol.autoDestroy){this.protocol.destroy();}
+this.protocol=null;}
+this.destroyFeatures();this.features=null;this.selectedFeatures=null;this.unrenderedFeatures=null;if(this.renderer){this.renderer.destroy();}
+this.renderer=null;this.geometryType=null;this.drawn=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Vector(this.name,this.getOptions());}
+obj=OpenLayers.Layer.prototype.clone.apply(this,[obj]);var features=this.features;var len=features.length;var clonedFeatures=new Array(len);for(var i=0;i<len;++i){clonedFeatures[i]=features[i].clone();}
+obj.features=clonedFeatures;return obj;},refresh:function(obj){if(this.calculateInRange()&&this.visibility){this.events.triggerEvent("refresh",obj);}},assignRenderer:function(){for(var i=0,len=this.renderers.length;i<len;i++){var rendererClass=this.renderers[i];var renderer=(typeof rendererClass=="function")?rendererClass:OpenLayers.Renderer[rendererClass];if(renderer&&renderer.prototype.supported()){this.renderer=new renderer(this.div,this.rendererOptions);break;}}},displayError:function(){if(this.reportError){OpenLayers.Console.userError(OpenLayers.i18n("browserNotSupported",{'renderers':this.renderers.join("\n")}));}},setMap:function(map){OpenLayers.Layer.prototype.setMap.apply(this,arguments);if(!this.renderer){this.map.removeLayer(this);}else{this.renderer.map=this.map;this.renderer.setSize(this.map.getSize());}},afterAdd:function(){if(this.strategies){var strategy,i,len;for(i=0,len=this.strategies.length;i<len;i++){strategy=this.strategies[i];if(strategy.autoActivate){strategy.activate();}}}},removeMap:function(map){this.drawn=false;if(this.strategies){var strategy,i,len;for(i=0,len=this.strategies.length;i<len;i++){strategy=this.strategies[i];if(strategy.autoActivate){strategy.deactivate();}}}},onMapResize:function(){OpenLayers.Layer.prototype.onMapResize.apply(this,arguments);this.renderer.setSize(this.map.getSize());},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);var coordSysUnchanged=true;if(!dragging){this.renderer.root.style.visibility="hidden";this.div.style.left=-parseInt(this.map.layerContainerDiv.style.left)+"px";this.div.style.top=-parseInt(this.map.layerContainerDiv.style.top)+"px";var extent=this.map.getExtent();coordSysUnchanged=this.renderer.setExtent(extent,zoomChanged);this.renderer.root.style.visibility="visible";if(navigator.userAgent.toLowerCase().indexOf("gecko")!=-1){this.div.scrollLeft=this.div.scrollLeft;}
+if(!zoomChanged&&coordSysUnchanged){for(var i in this.unrenderedFeatures){var feature=this.unrenderedFeatures[i];this.drawFeature(feature);}}}
+if(!this.drawn||zoomChanged||!coordSysUnchanged){this.drawn=true;var feature;for(var i=0,len=this.features.length;i<len;i++){this.renderer.locked=(i!==(len-1));feature=this.features[i];this.drawFeature(feature);}}},display:function(display){OpenLayers.Layer.prototype.display.apply(this,arguments);var currentDisplay=this.div.style.display;if(currentDisplay!=this.renderer.root.style.display){this.renderer.root.style.display=currentDisplay;}},addFeatures:function(features,options){if(!(features instanceof Array)){features=[features];}
+var notify=!options||!options.silent;if(notify){var event={features:features};var ret=this.events.triggerEvent("beforefeaturesadded",event);if(ret===false){return;}
+features=event.features;}
+var featuresAdded=[];for(var i=0,len=features.length;i<len;i++){if(i!=(features.length-1)){this.renderer.locked=true;}else{this.renderer.locked=false;}
+var feature=features[i];if(this.geometryType&&!(feature.geometry instanceof this.geometryType)){var throwStr=OpenLayers.i18n('componentShouldBe',{'geomType':this.geometryType.prototype.CLASS_NAME});throw throwStr;}
+feature.layer=this;if(!feature.style&&this.style){feature.style=OpenLayers.Util.extend({},this.style);}
+if(notify){if(this.events.triggerEvent("beforefeatureadded",{feature:feature})===false){continue;};this.preFeatureInsert(feature);}
+featuresAdded.push(feature);this.features.push(feature);this.drawFeature(feature);if(notify){this.events.triggerEvent("featureadded",{feature:feature});this.onFeatureInsert(feature);}}
+if(notify){this.events.triggerEvent("featuresadded",{features:featuresAdded});}},removeFeatures:function(features,options){if(!features||features.length===0){return;}
+if(features===this.features){return this.removeAllFeatures(options);}
+if(!(features instanceof Array)){features=[features];}
+if(features===this.selectedFeatures){features=features.slice();}
+var notify=!options||!options.silent;if(notify){this.events.triggerEvent("beforefeaturesremoved",{features:features});}
+for(var i=features.length-1;i>=0;i--){if(i!=0&&features[i-1].geometry){this.renderer.locked=true;}else{this.renderer.locked=false;}
+var feature=features[i];delete this.unrenderedFeatures[feature.id];if(notify){this.events.triggerEvent("beforefeatureremoved",{feature:feature});}
+this.features=OpenLayers.Util.removeItem(this.features,feature);feature.layer=null;if(feature.geometry){this.renderer.eraseFeatures(feature);}
+if(OpenLayers.Util.indexOf(this.selectedFeatures,feature)!=-1){OpenLayers.Util.removeItem(this.selectedFeatures,feature);}
+if(notify){this.events.triggerEvent("featureremoved",{feature:feature});}}
+if(notify){this.events.triggerEvent("featuresremoved",{features:features});}},removeAllFeatures:function(options){var notify=!options||!options.silent;var features=this.features;if(notify){this.events.triggerEvent("beforefeaturesremoved",{features:features});}
+var feature;for(var i=features.length-1;i>=0;i--){feature=features[i];if(notify){this.events.triggerEvent("beforefeatureremoved",{feature:feature});}
+feature.layer=null;if(notify){this.events.triggerEvent("featureremoved",{feature:feature});}}
+this.renderer.clear();this.features=[];this.unrenderedFeatures={};this.selectedFeatures=[];if(notify){this.events.triggerEvent("featuresremoved",{features:features});}},destroyFeatures:function(features,options){var all=(features==undefined);if(all){features=this.features;}
+if(features){this.removeFeatures(features,options);for(var i=features.length-1;i>=0;i--){features[i].destroy();}}},drawFeature:function(feature,style){if(!this.drawn){return}
+if(typeof style!="object"){if(!style&&feature.state===OpenLayers.State.DELETE){style="delete";}
+var renderIntent=style||feature.renderIntent;style=feature.style||this.style;if(!style){style=this.styleMap.createSymbolizer(feature,renderIntent);}}
+if(!this.renderer.drawFeature(feature,style)){this.unrenderedFeatures[feature.id]=feature;}else{delete this.unrenderedFeatures[feature.id];};},eraseFeatures:function(features){this.renderer.eraseFeatures(features);},getFeatureFromEvent:function(evt){if(!this.renderer){OpenLayers.Console.error(OpenLayers.i18n("getFeatureError"));return null;}
+var featureId=this.renderer.getFeatureIdFromEvent(evt);return this.getFeatureById(featureId);},getFeatureBy:function(property,value){var feature=null;for(var i=0,len=this.features.length;i<len;++i){if(this.features[i][property]==value){feature=this.features[i];break;}}
+return feature;},getFeatureById:function(featureId){return this.getFeatureBy('id',featureId);},getFeatureByFid:function(featureFid){return this.getFeatureBy('fid',featureFid);},onFeatureInsert:function(feature){},preFeatureInsert:function(feature){},getDataExtent:function(){var maxExtent=null;var features=this.features;if(features&&(features.length>0)){maxExtent=new OpenLayers.Bounds();var geometry=null;for(var i=0,len=features.length;i<len;i++){geometry=features[i].geometry;if(geometry){maxExtent.extend(geometry.getBounds());}}}
+return maxExtent;},CLASS_NAME:"OpenLayers.Layer.Vector"});OpenLayers.Layer.WMS.Post=OpenLayers.Class(OpenLayers.Layer.WMS,{tileClass:null,unsupportedBrowsers:["mozilla","firefox","opera"],SUPPORTED_TRANSITIONS:[],initialize:function(name,url,params,options){var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.WMS.prototype.initialize.apply(this,newArguments);this.tileClass=OpenLayers.Util.indexOf(this.unsupportedBrowsers,OpenLayers.Util.getBrowserName())!=-1?OpenLayers.Tile.Image:OpenLayers.Tile.Image.IFrame;},addTile:function(bounds,position){return new this.tileClass(this,position,bounds,null,this.tileSize);},CLASS_NAME:'OpenLayers.Layer.WMS.Post'});OpenLayers.Layer.WMS.Untiled=OpenLayers.Class(OpenLayers.Layer.WMS,{singleTile:true,initialize:function(name,url,params,options){OpenLayers.Layer.WMS.prototype.initialize.apply(this,arguments);var msg="The OpenLayers.Layer.WMS.Untiled class is deprecated and "+"will be removed in 3.0. Instead, you should use the "+"normal OpenLayers.Layer.WMS class, passing it the option "+"'singleTile' as true.";OpenLayers.Console.warn(msg);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WMS.Untiled(this.name,this.url,this.params,this.getOptions());}
+obj=OpenLayers.Layer.WMS.prototype.clone.apply(this,[obj]);return obj;},CLASS_NAME:"OpenLayers.Layer.WMS.Untiled"});OpenLayers.Strategy.Filter=OpenLayers.Class(OpenLayers.Strategy,{filter:null,cache:null,caching:false,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);if(!this.filter||!(this.filter instanceof OpenLayers.Filter)){throw new Error("Filter strategy must be constructed with a filter");}},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.apply(this,arguments);if(activated){this.cache=[];this.layer.events.on({"beforefeaturesadded":this.handleAdd,"beforefeaturesremoved":this.handleRemove,scope:this});}
+return activated;},deactivate:function(){this.cache=null;if(this.layer&&this.layer.events){this.layer.events.un({"beforefeaturesadded":this.handleAdd,"beforefeaturesremoved":this.handleRemove,scope:this});}
+return OpenLayers.Strategy.prototype.deactivate.apply(this,arguments);},handleAdd:function(event){if(!this.caching){var features=event.features;event.features=[];var feature;for(var i=0,ii=features.length;i<ii;++i){feature=features[i];if(this.filter.evaluate(feature)){event.features.push(feature);}else{this.cache.push(feature);}}}},handleRemove:function(event){if(!this.caching){this.cache=[];}},setFilter:function(filter){this.filter=filter;var previousCache=this.cache;this.cache=[];this.handleAdd({features:this.layer.features});if(this.cache.length>0){this.caching=true;this.layer.removeFeatures(this.cache.slice(),{silent:true});this.caching=false;}
+if(previousCache.length>0){var event={features:previousCache};this.handleAdd(event);this.caching=true;this.layer.addFeatures(event.features,{silent:true});this.caching=false;}},CLASS_NAME:"OpenLayers.Strategy.Filter"});OpenLayers.Style2=OpenLayers.Class({id:null,name:null,title:null,description:null,layerName:null,isDefault:false,rules:null,initialize:function(config){OpenLayers.Util.extend(this,config);this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){for(var i=0,len=this.rules.length;i<len;i++){this.rules[i].destroy();}
+delete this.rules;},clone:function(){var config=OpenLayers.Util.extend({},this);if(this.rules){config.rules=[];for(var i=0,len=this.rules.length;i<len;++i){config.rules.push(this.rules[i].clone());}}
+return new OpenLayers.Style2(config);},CLASS_NAME:"OpenLayers.Style2"});OpenLayers.Control.GetFeature=OpenLayers.Class(OpenLayers.Control,{protocol:null,multipleKey:null,toggleKey:null,modifiers:null,multiple:false,click:true,single:true,clickout:true,toggle:false,clickTolerance:5,hover:false,box:false,maxFeatures:10,features:null,hoverFeature:null,handlerOptions:null,handlers:null,hoverResponse:null,filterType:OpenLayers.Filter.Spatial.BBOX,EVENT_TYPES:["featureselected","featuresselected","featureunselected","clickout","beforefeatureselected","beforefeaturesselected","hoverfeature","outfeature"],initialize:function(options){this.EVENT_TYPES=OpenLayers.Control.GetFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);options.handlerOptions=options.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[options]);this.features={};this.handlers={};if(this.click){this.handlers.click=new OpenLayers.Handler.Click(this,{click:this.selectClick},this.handlerOptions.click||{});}
+if(this.box){this.handlers.box=new OpenLayers.Handler.Box(this,{done:this.selectBox},OpenLayers.Util.extend(this.handlerOptions.box,{boxDivClassName:"olHandlerBoxSelectFeature"}));}
+if(this.hover){this.handlers.hover=new OpenLayers.Handler.Hover(this,{'move':this.cancelHover,'pause':this.selectHover},OpenLayers.Util.extend(this.handlerOptions.hover,{'delay':250}));}},activate:function(){if(!this.active){for(var i in this.handlers){this.handlers[i].activate();}}
+return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){if(this.active){for(var i in this.handlers){this.handlers[i].deactivate();}}
+return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},selectClick:function(evt){var bounds=this.pixelToBounds(evt.xy);this.setModifiers(evt);this.request(bounds,{single:this.single});},selectBox:function(position){var bounds;if(position instanceof OpenLayers.Bounds){var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));bounds=new OpenLayers.Bounds(minXY.lon,minXY.lat,maxXY.lon,maxXY.lat);}else{if(this.click){return;}
+bounds=this.pixelToBounds(position);}
+this.setModifiers(this.handlers.box.dragHandler.evt);this.request(bounds);},selectHover:function(evt){var bounds=this.pixelToBounds(evt.xy);this.request(bounds,{single:true,hover:true});},cancelHover:function(){if(this.hoverResponse){this.protocol.abort(this.hoverResponse);this.hoverResponse=null;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");}},request:function(bounds,options){options=options||{};var filter=new OpenLayers.Filter.Spatial({type:this.filterType,value:bounds});OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait");var response=this.protocol.read({maxFeatures:options.single==true?this.maxFeatures:undefined,filter:filter,callback:function(result){if(result.success()){if(result.features.length){if(options.single==true){this.selectBestFeature(result.features,bounds.getCenterLonLat(),options);}else{this.select(result.features);}}else if(options.hover){this.hoverSelect();}else{this.events.triggerEvent("clickout");if(this.clickout){this.unselectAll();}}}
+OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");},scope:this});if(options.hover==true){this.hoverResponse=response;}},selectBestFeature:function(features,clickPosition,options){options=options||{};if(features.length){var point=new OpenLayers.Geometry.Point(clickPosition.lon,clickPosition.lat);var feature,resultFeature,dist;var minDist=Number.MAX_VALUE;for(var i=0;i<features.length;++i){feature=features[i];if(feature.geometry){dist=point.distanceTo(feature.geometry,{edge:false});if(dist<minDist){minDist=dist;resultFeature=feature;if(minDist==0){break;}}}}
+if(options.hover==true){this.hoverSelect(resultFeature);}else{this.select(resultFeature||features);}}},setModifiers:function(evt){this.modifiers={multiple:this.multiple||(this.multipleKey&&evt[this.multipleKey]),toggle:this.toggle||(this.toggleKey&&evt[this.toggleKey])};},select:function(features){if(!this.modifiers.multiple&&!this.modifiers.toggle){this.unselectAll();}
+if(!(features instanceof Array)){features=[features];}
+var cont=this.events.triggerEvent("beforefeaturesselected",{features:features});if(cont!==false){var selectedFeatures=[];var feature;for(var i=0,len=features.length;i<len;++i){feature=features[i];if(this.features[feature.fid||feature.id]){if(this.modifiers.toggle){this.unselect(this.features[feature.fid||feature.id]);}}else{cont=this.events.triggerEvent("beforefeatureselected",{feature:feature});if(cont!==false){this.features[feature.fid||feature.id]=feature;selectedFeatures.push(feature);this.events.triggerEvent("featureselected",{feature:feature});}}}
+this.events.triggerEvent("featuresselected",{features:selectedFeatures});}},hoverSelect:function(feature){var fid=feature?feature.fid||feature.id:null;var hfid=this.hoverFeature?this.hoverFeature.fid||this.hoverFeature.id:null;if(hfid&&hfid!=fid){this.events.triggerEvent("outfeature",{feature:this.hoverFeature});this.hoverFeature=null;}
+if(fid&&fid!=hfid){this.events.triggerEvent("hoverfeature",{feature:feature});this.hoverFeature=feature;}},unselect:function(feature){delete this.features[feature.fid||feature.id];this.events.triggerEvent("featureunselected",{feature:feature});},unselectAll:function(){for(var fid in this.features){this.unselect(this.features[fid]);}},setMap:function(map){for(var i in this.handlers){this.handlers[i].setMap(map);}
+OpenLayers.Control.prototype.setMap.apply(this,arguments);},pixelToBounds:function(pixel){var llPx=pixel.add(-this.clickTolerance/2,this.clickTolerance/2);var urPx=pixel.add(this.clickTolerance/2,-this.clickTolerance/2);var ll=this.map.getLonLatFromPixel(llPx);var ur=this.map.getLonLatFromPixel(urPx);return new OpenLayers.Bounds(ll.lon,ll.lat,ur.lon,ur.lat);},CLASS_NAME:"OpenLayers.Control.GetFeature"});OpenLayers.Control.Snapping=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforesnap","snap","unsnap"],DEFAULTS:{tolerance:10,node:true,edge:true,vertex:true},greedy:true,precedence:["node","vertex","edge"],resolution:null,geoToleranceCache:null,layer:null,feature:null,point:null,initialize:function(options){Array.prototype.push.apply(this.EVENT_TYPES,OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.options=options||{};if(this.options.layer){this.setLayer(this.options.layer);}
+var defaults=OpenLayers.Util.extend({},this.options.defaults);this.defaults=OpenLayers.Util.applyDefaults(defaults,this.DEFAULTS);this.setTargets(this.options.targets);if(this.targets.length===0&&this.layer){this.addTargetLayer(this.layer);}
+this.geoToleranceCache={};},setLayer:function(layer){if(this.active){this.deactivate();this.layer=layer;this.activate();}else{this.layer=layer;}},setTargets:function(targets){this.targets=[];if(targets&&targets.length){var target;for(var i=0,len=targets.length;i<len;++i){target=targets[i];if(target instanceof OpenLayers.Layer.Vector){this.addTargetLayer(target);}else{this.addTarget(target);}}}},addTargetLayer:function(layer){this.addTarget({layer:layer});},addTarget:function(target){target=OpenLayers.Util.applyDefaults(target,this.defaults);target.nodeTolerance=target.nodeTolerance||target.tolerance;target.vertexTolerance=target.vertexTolerance||target.tolerance;target.edgeTolerance=target.edgeTolerance||target.tolerance;this.targets.push(target);},removeTargetLayer:function(layer){var target;for(var i=this.targets.length-1;i>=0;--i){target=this.targets[i];if(target.layer===layer){this.removeTarget(target);}}},removeTarget:function(target){return OpenLayers.Util.removeItem(this.targets,target);},activate:function(){var activated=OpenLayers.Control.prototype.activate.call(this);if(activated){if(this.layer&&this.layer.events){this.layer.events.on({sketchstarted:this.onSketchModified,sketchmodified:this.onSketchModified,vertexmodified:this.onVertexModified,scope:this});}}
+return activated;},deactivate:function(){var deactivated=OpenLayers.Control.prototype.deactivate.call(this);if(deactivated){if(this.layer&&this.layer.events){this.layer.events.un({sketchstarted:this.onSketchModified,sketchmodified:this.onSketchModified,vertexmodified:this.onVertexModified,scope:this});}}
+this.feature=null;this.point=null;return deactivated;},onSketchModified:function(event){this.feature=event.feature;this.considerSnapping(event.vertex,event.vertex);},onVertexModified:function(event){this.feature=event.feature;var loc=this.layer.map.getLonLatFromViewPortPx(event.pixel);this.considerSnapping(event.vertex,new OpenLayers.Geometry.Point(loc.lon,loc.lat));},considerSnapping:function(point,loc){var best={rank:Number.POSITIVE_INFINITY,dist:Number.POSITIVE_INFINITY,x:null,y:null};var snapped=false;var result,target;for(var i=0,len=this.targets.length;i<len;++i){target=this.targets[i];result=this.testTarget(target,loc);if(result){if(this.greedy){best=result;best.target=target;snapped=true;break;}else{if((result.rank<best.rank)||(result.rank===best.rank&&result.dist<best.dist)){best=result;best.target=target;snapped=true;}}}}
+if(snapped){var proceed=this.events.triggerEvent("beforesnap",{point:point,x:best.x,y:best.y,distance:best.dist,layer:best.target.layer,snapType:this.precedence[best.rank]});if(proceed!==false){point.x=best.x;point.y=best.y;this.point=point;this.events.triggerEvent("snap",{point:point,snapType:this.precedence[best.rank],layer:best.target.layer,distance:best.dist});}else{snapped=false;}}
+if(this.point&&!snapped){point.x=loc.x;point.y=loc.y;this.point=null;this.events.triggerEvent("unsnap",{point:point});}},testTarget:function(target,loc){var tolerance={node:this.getGeoTolerance(target.nodeTolerance),vertex:this.getGeoTolerance(target.vertexTolerance),edge:this.getGeoTolerance(target.edgeTolerance)};var maxTolerance=Math.max(tolerance.node,tolerance.vertex,tolerance.edge);var result={rank:Number.POSITIVE_INFINITY,dist:Number.POSITIVE_INFINITY};var eligible=false;var features=target.layer.features;var feature,type,vertices,vertex,closest,dist,found;var numTypes=this.precedence.length;var ll=new OpenLayers.LonLat(loc.x,loc.y);for(var i=0,len=features.length;i<len;++i){feature=features[i];if(feature!==this.feature&&!feature._sketch&&feature.state!==OpenLayers.State.DELETE&&(!target.filter||target.filter.evaluate(feature.attributes))){if(feature.atPoint(ll,maxTolerance,maxTolerance)){for(var j=0,stop=Math.min(result.rank+1,numTypes);j<stop;++j){type=this.precedence[j];if(target[type]){if(type==="edge"){closest=feature.geometry.distanceTo(loc,{details:true});dist=closest.distance;if(dist<=tolerance[type]&&dist<result.dist){result={rank:j,dist:dist,x:closest.x0,y:closest.y0};eligible=true;break;}}else{vertices=feature.geometry.getVertices(type==="node");found=false;for(var k=0,klen=vertices.length;k<klen;++k){vertex=vertices[k];dist=vertex.distanceTo(loc);if(dist<=tolerance[type]&&(j<result.rank||(j===result.rank&&dist<result.dist))){result={rank:j,dist:dist,x:vertex.x,y:vertex.y};eligible=true;found=true;}}
+if(found){break;}}}}}}}
+return eligible?result:null;},getGeoTolerance:function(tolerance){var resolution=this.layer.map.getResolution();if(resolution!==this.resolution){this.resolution=resolution;this.geoToleranceCache={};}
+var geoTolerance=this.geoToleranceCache[tolerance];if(geoTolerance===undefined){geoTolerance=tolerance*resolution;this.geoToleranceCache[tolerance]=geoTolerance;}
+return geoTolerance;},destroy:function(){if(this.active){this.deactivate();}
+delete this.layer;delete this.targets;OpenLayers.Control.prototype.destroy.call(this);},CLASS_NAME:"OpenLayers.Control.Snapping"});OpenLayers.Format.Filter=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},write:function(filter,options){var version=(options&&options.version)||this.version||this.defaultVersion;if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.Filter["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a Filter parser for version "+
+version;}
+this.parser=new format(this.options);}
+return this.parser.write(filter);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var version=this.version;if(!version){version=this.defaultVersion;}
+if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.Filter["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a Filter parser for version "+
+version;}
+this.parser=new format(this.options);}
+var filter=this.parser.read(data);return filter;},CLASS_NAME:"OpenLayers.Format.Filter"});OpenLayers.Format.SLD=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,namedLayersAsArray:false,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},write:function(sld,options){var version=(options&&options.version)||this.version||this.defaultVersion;if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.SLD["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a SLD parser for version "+
+version;}
+this.parser=new format(this.options);}
+var root=this.parser.write(sld);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},read:function(data,options){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");if(!version){version=this.defaultVersion;}}
+if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.SLD["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a SLD parser for version "+
+version;}
+this.parser=new format(this.options);}
+var sld=this.parser.read(data,options);return sld;},CLASS_NAME:"OpenLayers.Format.SLD"});OpenLayers.Format.Text=OpenLayers.Class(OpenLayers.Format,{defaultStyle:null,extractStyles:true,initialize:function(options){options=options||{};if(options.extractStyles!==false){options.defaultStyle={'externalGraphic':OpenLayers.Util.getImagesLocation()+"marker.png",'graphicWidth':21,'graphicHeight':25,'graphicXOffset':-10.5,'graphicYOffset':-12.5};}
+OpenLayers.Format.prototype.initialize.apply(this,[options]);},read:function(text){var lines=text.split('\n');var columns;var features=[];for(var lcv=0;lcv<(lines.length-1);lcv++){var currLine=lines[lcv].replace(/^\s*/,'').replace(/\s*$/,'');if(currLine.charAt(0)!='#'){if(!columns){columns=currLine.split('\t');}else{var vals=currLine.split('\t');var geometry=new OpenLayers.Geometry.Point(0,0);var attributes={};var style=this.defaultStyle?OpenLayers.Util.applyDefaults({},this.defaultStyle):null;var icon,iconSize,iconOffset,overflow;var set=false;for(var valIndex=0;valIndex<vals.length;valIndex++){if(vals[valIndex]){if(columns[valIndex]=='point'){var coords=vals[valIndex].split(',');geometry.y=parseFloat(coords[0]);geometry.x=parseFloat(coords[1]);set=true;}else if(columns[valIndex]=='lat'){geometry.y=parseFloat(vals[valIndex]);set=true;}else if(columns[valIndex]=='lon'){geometry.x=parseFloat(vals[valIndex]);set=true;}else if(columns[valIndex]=='title')
+attributes['title']=vals[valIndex];else if(columns[valIndex]=='image'||columns[valIndex]=='icon'&&style){style['externalGraphic']=vals[valIndex];}else if(columns[valIndex]=='iconSize'&&style){var size=vals[valIndex].split(',');style['graphicWidth']=parseFloat(size[0]);style['graphicHeight']=parseFloat(size[1]);}else if(columns[valIndex]=='iconOffset'&&style){var offset=vals[valIndex].split(',');style['graphicXOffset']=parseFloat(offset[0]);style['graphicYOffset']=parseFloat(offset[1]);}else if(columns[valIndex]=='description'){attributes['description']=vals[valIndex];}else if(columns[valIndex]=='overflow'){attributes['overflow']=vals[valIndex];}else{attributes[columns[valIndex]]=vals[valIndex];}}}
+if(set){if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}
+var feature=new OpenLayers.Feature.Vector(geometry,attributes,style);features.push(feature);}}}}
+return features;},CLASS_NAME:"OpenLayers.Format.Text"});OpenLayers.Geometry.MultiPoint=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.Point"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},addPoint:function(point,index){this.addComponent(point,index);},removePoint:function(point){this.removeComponent(point);},CLASS_NAME:"OpenLayers.Geometry.MultiPoint"});OpenLayers.Handler.Point=OpenLayers.Class(OpenLayers.Handler,{point:null,layer:null,multi:false,drawing:false,mouseDown:false,lastDown:null,lastUp:null,persist:false,layerOptions:null,initialize:function(control,callbacks,options){if(!(options&&options.layerOptions&&options.layerOptions.styleMap)){this.style=OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'],{});}
+OpenLayers.Handler.prototype.initialize.apply(this,arguments);},activate:function(){if(!OpenLayers.Handler.prototype.activate.apply(this,arguments)){return false;}
+var options=OpenLayers.Util.extend({displayInLayerSwitcher:false,calculateInRange:OpenLayers.Function.True},this.layerOptions);this.layer=new OpenLayers.Layer.Vector(this.CLASS_NAME,options);this.map.addLayer(this.layer);return true;},createFeature:function(pixel){var lonlat=this.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.callback("create",[this.point.geometry,this.point]);this.point.geometry.clearBounds();this.layer.addFeatures([this.point],{silent:true});},deactivate:function(){if(!OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){return false;}
+if(this.drawing){this.cancel();}
+this.destroyFeature();if(this.layer.map!=null){this.layer.destroy(false);}
+this.layer=null;return true;},destroyFeature:function(){if(this.layer){this.layer.destroyFeatures();}
+this.point=null;},finalize:function(cancel){var key=cancel?"cancel":"done";this.drawing=false;this.mouseDown=false;this.lastDown=null;this.lastUp=null;this.callback(key,[this.geometryClone()]);if(cancel||!this.persist){this.destroyFeature();}},cancel:function(){this.finalize(true);},click:function(evt){OpenLayers.Event.stop(evt);return false;},dblclick:function(evt){OpenLayers.Event.stop(evt);return false;},modifyFeature:function(pixel){var lonlat=this.map.getLonLatFromPixel(pixel);this.point.geometry.x=lonlat.lon;this.point.geometry.y=lonlat.lat;this.callback("modify",[this.point.geometry,this.point]);this.point.geometry.clearBounds();this.drawFeature();},drawFeature:function(){this.layer.drawFeature(this.point,this.style);},getGeometry:function(){var geometry=this.point&&this.point.geometry;if(geometry&&this.multi){geometry=new OpenLayers.Geometry.MultiPoint([geometry]);}
+return geometry;},geometryClone:function(){var geom=this.getGeometry();return geom&&geom.clone();},mousedown:function(evt){if(!this.checkModifiers(evt)){return true;}
+if(this.lastDown&&this.lastDown.equals(evt.xy)){return true;}
+this.drawing=true;if(this.lastDown==null){if(this.persist){this.destroyFeature();}
+this.createFeature(evt.xy);}else{this.modifyFeature(evt.xy);}
+this.lastDown=evt.xy;return false;},mousemove:function(evt){if(this.drawing){this.modifyFeature(evt.xy);}
+return true;},mouseup:function(evt){if(this.drawing){this.finalize();return false;}else{return true;}},CLASS_NAME:"OpenLayers.Handler.Point"});OpenLayers.Layer.GML=OpenLayers.Class(OpenLayers.Layer.Vector,{loaded:false,format:null,formatOptions:null,initialize:function(name,url,options){var newArguments=[];newArguments.push(name,options);OpenLayers.Layer.Vector.prototype.initialize.apply(this,newArguments);this.url=url;},setVisibility:function(visibility,noEvent){OpenLayers.Layer.Vector.prototype.setVisibility.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadGML();}},moveTo:function(bounds,zoomChanged,minor){OpenLayers.Layer.Vector.prototype.moveTo.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadGML();}},loadGML:function(){if(!this.loaded){this.events.triggerEvent("loadstart");OpenLayers.Request.GET({url:this.url,success:this.requestSuccess,failure:this.requestFailure,scope:this});this.loaded=true;}},setUrl:function(url){this.url=url;this.destroyFeatures();this.loaded=false;this.loadGML();},requestSuccess:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
+var options={};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
+var gml=this.format?new this.format(options):new OpenLayers.Format.GML(options);this.addFeatures(gml.read(doc));this.events.triggerEvent("loadend");},requestFailure:function(request){OpenLayers.Console.userError(OpenLayers.i18n("errorLoadingGML",{'url':this.url}));this.events.triggerEvent("loadend");},CLASS_NAME:"OpenLayers.Layer.GML"});OpenLayers.Layer.PointTrack=OpenLayers.Class(OpenLayers.Layer.Vector,{dataFrom:null,initialize:function(name,options){OpenLayers.Layer.Vector.prototype.initialize.apply(this,arguments);},addNodes:function(pointFeatures){if(pointFeatures.length<2){OpenLayers.Console.error("At least two point features have to be added to create"+"a line from");return;}
+var lines=new Array(pointFeatures.length-1);var pointFeature,startPoint,endPoint;for(var i=0,len=pointFeatures.length;i<len;i++){pointFeature=pointFeatures[i];endPoint=pointFeature.geometry;if(!endPoint){var lonlat=pointFeature.lonlat;endPoint=new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);}else if(endPoint.CLASS_NAME!="OpenLayers.Geometry.Point"){OpenLayers.Console.error("Only features with point geometries are supported.");return;}
+if(i>0){var attributes=(this.dataFrom!=null)?(pointFeatures[i+this.dataFrom].data||pointFeatures[i+this.dataFrom].attributes):null;var line=new OpenLayers.Geometry.LineString([startPoint,endPoint]);lines[i-1]=new OpenLayers.Feature.Vector(line,attributes);}
+startPoint=endPoint;}
+this.addFeatures(lines);},CLASS_NAME:"OpenLayers.Layer.PointTrack"});OpenLayers.Layer.PointTrack.dataFrom={'SOURCE_NODE':-1,'TARGET_NODE':0};OpenLayers.Layer.Vector.RootContainer=OpenLayers.Class(OpenLayers.Layer.Vector,{displayInLayerSwitcher:false,layers:null,initialize:function(name,options){OpenLayers.Layer.Vector.prototype.initialize.apply(this,arguments);},display:function(){},getFeatureFromEvent:function(evt){var layers=this.layers;var feature;for(var i=0;i<layers.length;i++){feature=layers[i].getFeatureFromEvent(evt);if(feature){return feature;}}},setMap:function(map){OpenLayers.Layer.Vector.prototype.setMap.apply(this,arguments);this.collectRoots();map.events.register("changelayer",this,this.handleChangeLayer);},removeMap:function(map){map.events.unregister("changelayer",this,this.handleChangeLayer);this.resetRoots();OpenLayers.Layer.Vector.prototype.removeMap.apply(this,arguments);},collectRoots:function(){var layer;for(var i=0;i<this.map.layers.length;++i){layer=this.map.layers[i];if(OpenLayers.Util.indexOf(this.layers,layer)!=-1){layer.renderer.moveRoot(this.renderer);}}},resetRoots:function(){var layer;for(var i=0;i<this.layers.length;++i){layer=this.layers[i];if(this.renderer&&layer.renderer.getRenderLayerId()==this.id){this.renderer.moveRoot(layer.renderer);}}},handleChangeLayer:function(evt){var layer=evt.layer;if(evt.property=="order"&&OpenLayers.Util.indexOf(this.layers,layer)!=-1){this.resetRoots();this.collectRoots();}},CLASS_NAME:"OpenLayers.Layer.Vector.RootContainer"});OpenLayers.Layer.WFS=OpenLayers.Class(OpenLayers.Layer.Vector,OpenLayers.Layer.Markers,{isBaseLayer:false,tile:null,ratio:2,DEFAULT_PARAMS:{service:"WFS",version:"1.0.0",request:"GetFeature"},featureClass:null,format:null,formatObject:null,formatOptions:null,vectorMode:true,encodeBBOX:false,extractAttributes:false,initialize:function(name,url,params,options){if(options==undefined){options={};}
+if(options.featureClass||!OpenLayers.Layer.Vector||!OpenLayers.Feature.Vector){this.vectorMode=false;}
+params=OpenLayers.Util.upperCaseObject(params);OpenLayers.Util.extend(options,{'reportError':false});var newArguments=[];newArguments.push(name,options);OpenLayers.Layer.Vector.prototype.initialize.apply(this,newArguments);if(!this.renderer||!this.vectorMode){this.vectorMode=false;if(!options.featureClass){options.featureClass=OpenLayers.Feature.WFS;}
+OpenLayers.Layer.Markers.prototype.initialize.apply(this,newArguments);}
+if(this.params&&this.params.typename&&!this.options.typename){this.options.typename=this.params.typename;}
+if(!this.options.geometry_column){this.options.geometry_column="the_geom";}
+this.params=OpenLayers.Util.applyDefaults(params,OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS));this.url=url;},destroy:function(){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.destroy.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.destroy.apply(this,arguments);}
+if(this.tile){this.tile.destroy();}
+this.tile=null;this.ratio=null;this.featureClass=null;this.format=null;if(this.formatObject&&this.formatObject.destroy){this.formatObject.destroy();}
+this.formatObject=null;this.formatOptions=null;this.vectorMode=null;this.encodeBBOX=null;this.extractAttributes=null;},setMap:function(map){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.setMap.apply(this,arguments);var options={'extractAttributes':this.extractAttributes};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
+this.formatObject=this.format?new this.format(options):new OpenLayers.Format.GML(options);}else{OpenLayers.Layer.Markers.prototype.setMap.apply(this,arguments);}},moveTo:function(bounds,zoomChanged,dragging){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.moveTo.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);}
+if(dragging){return false;}
+if(zoomChanged){if(this.vectorMode){this.renderer.clear();}}
+if(this.options.minZoomLevel){OpenLayers.Console.warn(OpenLayers.i18n('minZoomLevelError'));if(this.map.getZoom()<this.options.minZoomLevel){return null;}}
+if(bounds==null){bounds=this.map.getExtent();}
+var firstRendering=(this.tile==null);var outOfBounds=(!firstRendering&&!this.tile.bounds.containsBounds(bounds));if(zoomChanged||firstRendering||(!dragging&&outOfBounds)){var center=bounds.getCenterLonLat();var tileWidth=bounds.getWidth()*this.ratio;var tileHeight=bounds.getHeight()*this.ratio;var tileBounds=new OpenLayers.Bounds(center.lon-(tileWidth/2),center.lat-(tileHeight/2),center.lon+(tileWidth/2),center.lat+(tileHeight/2));var tileSize=this.map.getSize();tileSize.w=tileSize.w*this.ratio;tileSize.h=tileSize.h*this.ratio;var ul=new OpenLayers.LonLat(tileBounds.left,tileBounds.top);var pos=this.map.getLayerPxFromLonLat(ul);var url=this.getFullRequestString();var params=null;var filter=this.params.filter||this.params.FILTER;if(filter){params={FILTER:filter};}
+else{params={BBOX:this.encodeBBOX?tileBounds.toBBOX():tileBounds.toArray()};}
+if(this.map&&!this.projection.equals(this.map.getProjectionObject())){var projectedBounds=tileBounds.clone();projectedBounds.transform(this.map.getProjectionObject(),this.projection);if(!filter){params.BBOX=this.encodeBBOX?projectedBounds.toBBOX():projectedBounds.toArray();}}
+url+="&"+OpenLayers.Util.getParameterString(params);if(!this.tile){this.tile=new OpenLayers.Tile.WFS(this,pos,tileBounds,url,tileSize);this.addTileMonitoringHooks(this.tile);this.tile.draw();}else{if(this.vectorMode){this.destroyFeatures();this.renderer.clear();}else{this.clearMarkers();}
+this.removeTileMonitoringHooks(this.tile);this.tile.destroy();this.tile=null;this.tile=new OpenLayers.Tile.WFS(this,pos,tileBounds,url,tileSize);this.addTileMonitoringHooks(this.tile);this.tile.draw();}}},addTileMonitoringHooks:function(tile){tile.onLoadStart=function(){if(this==this.layer.tile){this.layer.events.triggerEvent("loadstart");}};tile.events.register("loadstart",tile,tile.onLoadStart);tile.onLoadEnd=function(){if(this==this.layer.tile){this.layer.events.triggerEvent("tileloaded");this.layer.events.triggerEvent("loadend");}};tile.events.register("loadend",tile,tile.onLoadEnd);tile.events.register("unload",tile,tile.onLoadEnd);},removeTileMonitoringHooks:function(tile){tile.unload();tile.events.un({"loadstart":tile.onLoadStart,"loadend":tile.onLoadEnd,"unload":tile.onLoadEnd,scope:tile});},onMapResize:function(){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.onMapResize.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.onMapResize.apply(this,arguments);}},display:function(){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.display.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.display.apply(this,arguments);}},mergeNewParams:function(newParams){var upperParams=OpenLayers.Util.upperCaseObject(newParams);var newArguments=[upperParams];return OpenLayers.Layer.HTTPRequest.prototype.mergeNewParams.apply(this,newArguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WFS(this.name,this.url,this.params,this.getOptions());}
+if(this.vectorMode){obj=OpenLayers.Layer.Vector.prototype.clone.apply(this,[obj]);}else{obj=OpenLayers.Layer.Markers.prototype.clone.apply(this,[obj]);}
+return obj;},getFullRequestString:function(newParams,altUrl){var projectionCode=this.projection.getCode()||this.map.getProjection();this.params.SRS=(projectionCode=="none")?null:projectionCode;return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this,arguments);},commit:function(){if(!this.writer){var options={};if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
+this.writer=new OpenLayers.Format.WFS(options,this);}
+var data=this.writer.write(this.features);OpenLayers.Request.POST({url:this.url,data:data,success:this.commitSuccess,failure:this.commitFailure,scope:this});},commitSuccess:function(request){var response=request.responseText;if(response.indexOf('SUCCESS')!=-1){this.commitReport(OpenLayers.i18n("commitSuccess",{'response':response}));for(var i=0;i<this.features.length;i++){this.features[i].state=null;}}else if(response.indexOf('FAILED')!=-1||response.indexOf('Exception')!=-1){this.commitReport(OpenLayers.i18n("commitFailed",{'response':response}));}},commitFailure:function(request){},commitReport:function(string,response){OpenLayers.Console.userError(string);},refresh:function(){if(this.tile){if(this.vectorMode){this.renderer.clear();this.features.length=0;}else{this.clearMarkers();this.markers.length=0;}
+this.tile.draw();}},getDataExtent:function(){var extent;if(this.vectorMode){extent=OpenLayers.Layer.Vector.prototype.getDataExtent.apply(this);}else{extent=OpenLayers.Layer.Markers.prototype.getDataExtent.apply(this);}
+return extent;},setOpacity:function(opacity){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.setOpacity.apply(this,[opacity]);}else{OpenLayers.Layer.Markers.prototype.setOpacity.apply(this,[opacity]);}},CLASS_NAME:"OpenLayers.Layer.WFS"});OpenLayers.Protocol.HTTP=OpenLayers.Class(OpenLayers.Protocol,{url:null,headers:null,params:null,callback:null,scope:null,readWithPOST:false,wildcarded:false,initialize:function(options){options=options||{};this.params={};this.headers={};OpenLayers.Protocol.prototype.initialize.apply(this,arguments);},destroy:function(){this.params=null;this.headers=null;OpenLayers.Protocol.prototype.destroy.apply(this);},read:function(options){OpenLayers.Protocol.prototype.read.apply(this,arguments);options=OpenLayers.Util.applyDefaults(options,this.options);options.params=OpenLayers.Util.applyDefaults(options.params,this.options.params);if(options.filter){options.params=this.filterToParams(options.filter,options.params);}
+var readWithPOST=(options.readWithPOST!==undefined)?options.readWithPOST:this.readWithPOST;var resp=new OpenLayers.Protocol.Response({requestType:"read"});if(readWithPOST){resp.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleRead,resp,options),data:OpenLayers.Util.getParameterString(options.params),headers:{"Content-Type":"application/x-www-form-urlencoded"}});}else{resp.priv=OpenLayers.Request.GET({url:options.url,callback:this.createCallback(this.handleRead,resp,options),params:options.params,headers:options.headers});}
+return resp;},handleRead:function(resp,options){this.handleResponse(resp,options);},filterToParams:function(filter,params){params=params||{};var className=filter.CLASS_NAME;var filterType=className.substring(className.lastIndexOf(".")+1);switch(filterType){case"Spatial":switch(filter.type){case OpenLayers.Filter.Spatial.BBOX:params.bbox=filter.value.toArray();break;case OpenLayers.Filter.Spatial.DWITHIN:params.tolerance=filter.distance;case OpenLayers.Filter.Spatial.WITHIN:params.lon=filter.value.x;params.lat=filter.value.y;break;default:OpenLayers.Console.warn("Unknown spatial filter type "+filter.type);}
+break;case"Comparison":var op=OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR[filter.type];if(op!==undefined){var value=filter.value;if(filter.type==OpenLayers.Filter.Comparison.LIKE){value=this.regex2value(value);if(this.wildcarded){value="%"+value+"%";}}
+params[filter.property+"__"+op]=value;params.queryable=params.queryable||[];params.queryable.push(filter.property);}else{OpenLayers.Console.warn("Unknown comparison filter type "+filter.type);}
+break;case"Logical":if(filter.type===OpenLayers.Filter.Logical.AND){for(var i=0,len=filter.filters.length;i<len;i++){params=this.filterToParams(filter.filters[i],params);}}else{OpenLayers.Console.warn("Unsupported logical filter type "+filter.type);}
+break;default:OpenLayers.Console.warn("Unknown filter type "+filterType);}
+return params;},regex2value:function(value){value=value.replace(/%/g,"\\%");value=value.replace(/\\\\\.(\*)?/g,function($0,$1){return $1?$0:"\\\\_";});value=value.replace(/\\\\\.\*/g,"\\\\%");value=value.replace(/(\\)?\.(\*)?/g,function($0,$1,$2){return $1||$2?$0:"_";});value=value.replace(/(\\)?\.\*/g,function($0,$1){return $1?$0:"%";});value=value.replace(/\\\./g,".");value=value.replace(/(\\)?\\\*/g,function($0,$1){return $1?$0:"*";});return value;},create:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=new OpenLayers.Protocol.Response({reqFeatures:features,requestType:"create"});resp.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleCreate,resp,options),headers:options.headers,data:this.format.write(features)});return resp;},handleCreate:function(resp,options){this.handleResponse(resp,options);},update:function(feature,options){options=options||{};var url=options.url||feature.url||this.options.url+"/"+feature.fid;options=OpenLayers.Util.applyDefaults(options,this.options);var resp=new OpenLayers.Protocol.Response({reqFeatures:feature,requestType:"update"});resp.priv=OpenLayers.Request.PUT({url:url,callback:this.createCallback(this.handleUpdate,resp,options),headers:options.headers,data:this.format.write(feature)});return resp;},handleUpdate:function(resp,options){this.handleResponse(resp,options);},"delete":function(feature,options){options=options||{};var url=options.url||feature.url||this.options.url+"/"+feature.fid;options=OpenLayers.Util.applyDefaults(options,this.options);var resp=new OpenLayers.Protocol.Response({reqFeatures:feature,requestType:"delete"});resp.priv=OpenLayers.Request.DELETE({url:url,callback:this.createCallback(this.handleDelete,resp,options),headers:options.headers});return resp;},handleDelete:function(resp,options){this.handleResponse(resp,options);},handleResponse:function(resp,options){var request=resp.priv;if(options.callback){if(request.status>=200&&request.status<300){if(resp.requestType!="delete"){resp.features=this.parseFeatures(request);}
+resp.code=OpenLayers.Protocol.Response.SUCCESS;}else{resp.code=OpenLayers.Protocol.Response.FAILURE;}
+options.callback.call(options.scope,resp);}},parseFeatures:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
+if(!doc||doc.length<=0){return null;}
+return this.format.read(doc);},commit:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=[],nResponses=0;var types={};types[OpenLayers.State.INSERT]=[];types[OpenLayers.State.UPDATE]=[];types[OpenLayers.State.DELETE]=[];var feature,list,requestFeatures=[];for(var i=0,len=features.length;i<len;++i){feature=features[i];list=types[feature.state];if(list){list.push(feature);requestFeatures.push(feature);}}
+var nRequests=(types[OpenLayers.State.INSERT].length>0?1:0)+
+types[OpenLayers.State.UPDATE].length+
+types[OpenLayers.State.DELETE].length;var success=true;var finalResponse=new OpenLayers.Protocol.Response({reqFeatures:requestFeatures});function insertCallback(response){var len=response.features?response.features.length:0;var fids=new Array(len);for(var i=0;i<len;++i){fids[i]=response.features[i].fid;}
+finalResponse.insertIds=fids;callback.apply(this,[response]);}
+function callback(response){this.callUserCallback(response,options);success=success&&response.success();nResponses++;if(nResponses>=nRequests){if(options.callback){finalResponse.code=success?OpenLayers.Protocol.Response.SUCCESS:OpenLayers.Protocol.Response.FAILURE;options.callback.apply(options.scope,[finalResponse]);}}}
+var queue=types[OpenLayers.State.INSERT];if(queue.length>0){resp.push(this.create(queue,OpenLayers.Util.applyDefaults({callback:insertCallback,scope:this},options.create)));}
+queue=types[OpenLayers.State.UPDATE];for(var i=queue.length-1;i>=0;--i){resp.push(this.update(queue[i],OpenLayers.Util.applyDefaults({callback:callback,scope:this},options.update)));}
+queue=types[OpenLayers.State.DELETE];for(var i=queue.length-1;i>=0;--i){resp.push(this["delete"](queue[i],OpenLayers.Util.applyDefaults({callback:callback,scope:this},options["delete"])));}
+return resp;},abort:function(response){if(response){response.priv.abort();}},callUserCallback:function(resp,options){var opt=options[resp.requestType];if(opt&&opt.callback){opt.callback.call(opt.scope,resp);}},CLASS_NAME:"OpenLayers.Protocol.HTTP"});(function(){var o=OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR={};o[OpenLayers.Filter.Comparison.EQUAL_TO]="eq";o[OpenLayers.Filter.Comparison.NOT_EQUAL_TO]="ne";o[OpenLayers.Filter.Comparison.LESS_THAN]="lt";o[OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO]="lte";o[OpenLayers.Filter.Comparison.GREATER_THAN]="gt";o[OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO]="gte";o[OpenLayers.Filter.Comparison.LIKE]="ilike";})();OpenLayers.Strategy.BBOX=OpenLayers.Class(OpenLayers.Strategy,{bounds:null,resolution:null,ratio:2,resFactor:null,response:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){this.layer.events.on({"moveend":this.update,scope:this});this.layer.events.on({"refresh":this.update,scope:this});}
+return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.layer.events.un({"moveend":this.update,scope:this});this.layer.events.un({"refresh":this.update,scope:this});}
+return deactivated;},update:function(options){var mapBounds=this.getMapBounds();if((options&&options.force)||this.invalidBounds(mapBounds)){this.calculateBounds(mapBounds);this.resolution=this.layer.map.getResolution();this.triggerRead();}},getMapBounds:function(){var bounds=this.layer.map.getExtent();if(!this.layer.projection.equals(this.layer.map.getProjectionObject())){bounds=bounds.clone().transform(this.layer.map.getProjectionObject(),this.layer.projection);}
+return bounds;},invalidBounds:function(mapBounds){if(!mapBounds){mapBounds=this.getMapBounds();}
+var invalid=!this.bounds||!this.bounds.containsBounds(mapBounds);if(!invalid&&this.resFactor){var ratio=this.resolution/this.layer.map.getResolution();invalid=(ratio>=this.resFactor||ratio<=(1/this.resFactor));}
+return invalid;},calculateBounds:function(mapBounds){if(!mapBounds){mapBounds=this.getMapBounds();}
+var center=mapBounds.getCenterLonLat();var dataWidth=mapBounds.getWidth()*this.ratio;var dataHeight=mapBounds.getHeight()*this.ratio;this.bounds=new OpenLayers.Bounds(center.lon-(dataWidth/2),center.lat-(dataHeight/2),center.lon+(dataWidth/2),center.lat+(dataHeight/2));},triggerRead:function(){if(this.response){this.layer.protocol.abort(this.response);this.layer.events.triggerEvent("loadend");}
+this.layer.events.triggerEvent("loadstart");this.response=this.layer.protocol.read({filter:this.createFilter(),callback:this.merge,scope:this});},createFilter:function(){var filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.BBOX,value:this.bounds,projection:this.layer.projection});if(this.layer.filter){filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND,filters:[this.layer.filter,filter]});}
+return filter;},merge:function(resp){this.layer.destroyFeatures();var features=resp.features;if(features&&features.length>0){var remote=this.layer.projection;var local=this.layer.map.getProjectionObject();if(!local.equals(remote)){var geom;for(var i=0,len=features.length;i<len;++i){geom=features[i].geometry;if(geom){geom.transform(remote,local);}}}
+this.layer.addFeatures(features);}
+this.response=null;this.layer.events.triggerEvent("loadend");},CLASS_NAME:"OpenLayers.Strategy.BBOX"});OpenLayers.Control.SelectFeature=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforefeaturehighlighted","featurehighlighted","featureunhighlighted"],multipleKey:null,toggleKey:null,multiple:false,clickout:true,toggle:false,hover:false,highlightOnly:false,box:false,onBeforeSelect:function(){},onSelect:function(){},onUnselect:function(){},scope:null,geometryTypes:null,layer:null,layers:null,callbacks:null,selectStyle:null,renderIntent:"select",handlers:null,initialize:function(layers,options){this.EVENT_TYPES=OpenLayers.Control.SelectFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);if(this.scope===null){this.scope=this;}
+this.initLayer(layers);var callbacks={click:this.clickFeature,clickout:this.clickoutFeature};if(this.hover){callbacks.over=this.overFeature;callbacks.out=this.outFeature;}
+this.callbacks=OpenLayers.Util.extend(callbacks,this.callbacks);this.handlers={feature:new OpenLayers.Handler.Feature(this,this.layer,this.callbacks,{geometryTypes:this.geometryTypes})};if(this.box){this.handlers.box=new OpenLayers.Handler.Box(this,{done:this.selectBox},{boxDivClassName:"olHandlerBoxSelectFeature"});}},initLayer:function(layers){if(layers instanceof Array){this.layers=layers;this.layer=new OpenLayers.Layer.Vector.RootContainer(this.id+"_container",{layers:layers});}else{this.layer=layers;}},destroy:function(){if(this.active&&this.layers){this.map.removeLayer(this.layer);}
+OpenLayers.Control.prototype.destroy.apply(this,arguments);if(this.layers){this.layer.destroy();}},activate:function(){if(!this.active){if(this.layers){this.map.addLayer(this.layer);}
+this.handlers.feature.activate();if(this.box&&this.handlers.box){this.handlers.box.activate();}}
+return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){if(this.active){this.handlers.feature.deactivate();if(this.handlers.box){this.handlers.box.deactivate();}
+if(this.layers){this.map.removeLayer(this.layer);}}
+return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},unselectAll:function(options){var layers=this.layers||[this.layer];var layer,feature;for(var l=0;l<layers.length;++l){layer=layers[l];for(var i=layer.selectedFeatures.length-1;i>=0;--i){feature=layer.selectedFeatures[i];if(!options||options.except!=feature){this.unselect(feature);}}}},clickFeature:function(feature){if(!this.hover){var selected=(OpenLayers.Util.indexOf(feature.layer.selectedFeatures,feature)>-1);if(selected){if(this.toggleSelect()){this.unselect(feature);}else if(!this.multipleSelect()){this.unselectAll({except:feature});}}else{if(!this.multipleSelect()){this.unselectAll({except:feature});}
+this.select(feature);}}},multipleSelect:function(){return this.multiple||(this.handlers.feature.evt&&this.handlers.feature.evt[this.multipleKey]);},toggleSelect:function(){return this.toggle||(this.handlers.feature.evt&&this.handlers.feature.evt[this.toggleKey]);},clickoutFeature:function(feature){if(!this.hover&&this.clickout){this.unselectAll();}},overFeature:function(feature){var layer=feature.layer;if(this.hover){if(this.highlightOnly){this.highlight(feature);}else if(OpenLayers.Util.indexOf(layer.selectedFeatures,feature)==-1){this.select(feature);}}},outFeature:function(feature){if(this.hover){if(this.highlightOnly){if(feature._lastHighlighter==this.id){if(feature._prevHighlighter&&feature._prevHighlighter!=this.id){delete feature._lastHighlighter;var control=this.map.getControl(feature._prevHighlighter);if(control){control.highlight(feature);}}else{this.unhighlight(feature);}}}else{this.unselect(feature);}}},highlight:function(feature){var layer=feature.layer;var cont=this.events.triggerEvent("beforefeaturehighlighted",{feature:feature});if(cont!==false){feature._prevHighlighter=feature._lastHighlighter;feature._lastHighlighter=this.id;var style=this.selectStyle||this.renderIntent;layer.drawFeature(feature,style);this.events.triggerEvent("featurehighlighted",{feature:feature});}},unhighlight:function(feature){var layer=feature.layer;feature._lastHighlighter=feature._prevHighlighter;delete feature._prevHighlighter;layer.drawFeature(feature,feature.style||feature.layer.style||"default");this.events.triggerEvent("featureunhighlighted",{feature:feature});},select:function(feature){var cont=this.onBeforeSelect.call(this.scope,feature);var layer=feature.layer;if(cont!==false){cont=layer.events.triggerEvent("beforefeatureselected",{feature:feature});if(cont!==false){layer.selectedFeatures.push(feature);this.highlight(feature);if(!this.handlers.feature.lastFeature){this.handlers.feature.lastFeature=layer.selectedFeatures[0];}
+layer.events.triggerEvent("featureselected",{feature:feature});this.onSelect.call(this.scope,feature);}}},unselect:function(feature){var layer=feature.layer;this.unhighlight(feature);OpenLayers.Util.removeItem(layer.selectedFeatures,feature);layer.events.triggerEvent("featureunselected",{feature:feature});this.onUnselect.call(this.scope,feature);},selectBox:function(position){if(position instanceof OpenLayers.Bounds){var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));var bounds=new OpenLayers.Bounds(minXY.lon,minXY.lat,maxXY.lon,maxXY.lat);if(!this.multipleSelect()){this.unselectAll();}
+var prevMultiple=this.multiple;this.multiple=true;var layers=this.layers||[this.layer];var layer;for(var l=0;l<layers.length;++l){layer=layers[l];for(var i=0,len=layer.features.length;i<len;++i){var feature=layer.features[i];if(!feature.getVisibility()){continue;}
+if(this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)>-1){if(bounds.toGeometry().intersects(feature.geometry)){if(OpenLayers.Util.indexOf(layer.selectedFeatures,feature)==-1){this.select(feature);}}}}}
+this.multiple=prevMultiple;}},setMap:function(map){this.handlers.feature.setMap(map);if(this.box){this.handlers.box.setMap(map);}
+OpenLayers.Control.prototype.setMap.apply(this,arguments);},setLayer:function(layers){var isActive=this.active;this.unselectAll();this.deactivate();if(this.layers){this.layer.destroy();this.layers=null;}
+this.initLayer(layers);this.handlers.feature.layer=this.layer;if(isActive){this.activate();}},CLASS_NAME:"OpenLayers.Control.SelectFeature"});OpenLayers.Format.Filter.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ogc:"http://www.opengis.net/ogc",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"ogc",schemaLocation:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){var obj={};this.readers.ogc["Filter"].apply(this,[data,obj]);return obj.filter;},readers:{"ogc":{"Filter":function(node,parent){var obj={fids:[],filters:[]};this.readChildNodes(node,obj);if(obj.fids.length>0){parent.filter=new OpenLayers.Filter.FeatureId({fids:obj.fids});}else if(obj.filters.length>0){parent.filter=obj.filters[0];}},"FeatureId":function(node,obj){var fid=node.getAttribute("fid");if(fid){obj.fids.push(fid);}},"And":function(node,obj){var filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND});this.readChildNodes(node,filter);obj.filters.push(filter);},"Or":function(node,obj){var filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.OR});this.readChildNodes(node,filter);obj.filters.push(filter);},"Not":function(node,obj){var filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.NOT});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLessThan":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LESS_THAN});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsGreaterThan":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.GREATER_THAN});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLessThanOrEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsGreaterThanOrEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsBetween":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.BETWEEN});this.readChildNodes(node,filter);obj.filters.push(filter);},"Literal":function(node,obj){obj.value=OpenLayers.String.numericIf(this.getChildValue(node));},"PropertyName":function(node,filter){filter.property=this.getChildValue(node);},"LowerBoundary":function(node,filter){filter.lowerBoundary=OpenLayers.String.numericIf(this.readOgcExpression(node));},"UpperBoundary":function(node,filter){filter.upperBoundary=OpenLayers.String.numericIf(this.readOgcExpression(node));},"Intersects":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.INTERSECTS);},"Within":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.WITHIN);},"Contains":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.CONTAINS);},"DWithin":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.DWITHIN);},"Distance":function(node,obj){obj.distance=parseInt(this.getChildValue(node));obj.distanceUnits=node.getAttribute("units");}}},readSpatial:function(node,obj,type){var filter=new OpenLayers.Filter.Spatial({type:type});this.readChildNodes(node,filter);filter.value=filter.components[0];delete filter.components;obj.filters.push(filter);},readOgcExpression:function(node){var obj={};this.readChildNodes(node,obj);var value=obj.value;if(value===undefined){value=this.getChildValue(node);}
+return value;},write:function(filter){return this.writers.ogc["Filter"].apply(this,[filter]);},writers:{"ogc":{"Filter":function(filter){var node=this.createElementNSPlus("ogc:Filter");var sub=filter.CLASS_NAME.split(".").pop();if(sub=="FeatureId"){for(var i=0;i<filter.fids.length;++i){this.writeNode("FeatureId",filter.fids[i],node);}}else{this.writeNode(this.getFilterType(filter),filter,node);}
+return node;},"FeatureId":function(fid){return this.createElementNSPlus("ogc:FeatureId",{attributes:{fid:fid}});},"And":function(filter){var node=this.createElementNSPlus("ogc:And");var childFilter;for(var i=0;i<filter.filters.length;++i){childFilter=filter.filters[i];this.writeNode(this.getFilterType(childFilter),childFilter,node);}
+return node;},"Or":function(filter){var node=this.createElementNSPlus("ogc:Or");var childFilter;for(var i=0;i<filter.filters.length;++i){childFilter=filter.filters[i];this.writeNode(this.getFilterType(childFilter),childFilter,node);}
+return node;},"Not":function(filter){var node=this.createElementNSPlus("ogc:Not");var childFilter=filter.filters[0];this.writeNode(this.getFilterType(childFilter),childFilter,node);return node;},"PropertyIsLessThan":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLessThan");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsGreaterThan":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsGreaterThan");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsLessThanOrEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLessThanOrEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsGreaterThanOrEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsGreaterThanOrEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsBetween":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsBetween");this.writeNode("PropertyName",filter,node);this.writeNode("LowerBoundary",filter,node);this.writeNode("UpperBoundary",filter,node);return node;},"PropertyName":function(filter){return this.createElementNSPlus("ogc:PropertyName",{value:filter.property});},"Literal":function(value){return this.createElementNSPlus("ogc:Literal",{value:value});},"LowerBoundary":function(filter){var node=this.createElementNSPlus("ogc:LowerBoundary");this.writeNode("Literal",filter.lowerBoundary,node);return node;},"UpperBoundary":function(filter){var node=this.createElementNSPlus("ogc:UpperBoundary");this.writeNode("Literal",filter.upperBoundary,node);return node;},"INTERSECTS":function(filter){return this.writeSpatial(filter,"Intersects");},"WITHIN":function(filter){return this.writeSpatial(filter,"Within");},"CONTAINS":function(filter){return this.writeSpatial(filter,"Contains");},"DWITHIN":function(filter){var node=this.writeSpatial(filter,"DWithin");this.writeNode("Distance",filter,node);return node;},"Distance":function(filter){return this.createElementNSPlus("ogc:Distance",{attributes:{units:filter.distanceUnits},value:filter.distance});}}},getFilterType:function(filter){var filterType=this.filterMap[filter.type];if(!filterType){throw"Filter writing not supported for rule type: "+filter.type;}
+return filterType;},filterMap:{"&&":"And","||":"Or","!":"Not","==":"PropertyIsEqualTo","!=":"PropertyIsNotEqualTo","<":"PropertyIsLessThan",">":"PropertyIsGreaterThan","<=":"PropertyIsLessThanOrEqualTo",">=":"PropertyIsGreaterThanOrEqualTo","..":"PropertyIsBetween","~":"PropertyIsLike","BBOX":"BBOX","DWITHIN":"DWITHIN","WITHIN":"WITHIN","CONTAINS":"CONTAINS","INTERSECTS":"INTERSECTS"},CLASS_NAME:"OpenLayers.Format.Filter.v1"});OpenLayers.Geometry.Curve=OpenLayers.Class(OpenLayers.Geometry.MultiPoint,{componentTypes:["OpenLayers.Geometry.Point"],initialize:function(points){OpenLayers.Geometry.MultiPoint.prototype.initialize.apply(this,arguments);},getLength:function(){var length=0.0;if(this.components&&(this.components.length>1)){for(var i=1,len=this.components.length;i<len;i++){length+=this.components[i-1].distanceTo(this.components[i]);}}
+return length;},getGeodesicLength:function(projection){var geom=this;if(projection){var gg=new OpenLayers.Projection("EPSG:4326");if(!gg.equals(projection)){geom=this.clone().transform(projection,gg);}}
+var length=0.0;if(geom.components&&(geom.components.length>1)){var p1,p2;for(var i=1,len=geom.components.length;i<len;i++){p1=geom.components[i-1];p2=geom.components[i];length+=OpenLayers.Util.distVincenty({lon:p1.x,lat:p1.y},{lon:p2.x,lat:p2.y});}}
+return length*1000;},CLASS_NAME:"OpenLayers.Geometry.Curve"});OpenLayers.Layer.Text=OpenLayers.Class(OpenLayers.Layer.Markers,{location:null,features:null,formatOptions:null,selectedFeature:null,initialize:function(name,options){OpenLayers.Layer.Markers.prototype.initialize.apply(this,arguments);this.features=new Array();},destroy:function(){OpenLayers.Layer.Markers.prototype.destroy.apply(this,arguments);this.clearFeatures();this.features=null;},loadText:function(){if(!this.loaded){if(this.location!=null){var onFail=function(e){this.events.triggerEvent("loadend");};this.events.triggerEvent("loadstart");OpenLayers.Request.GET({url:this.location,success:this.parseData,failure:onFail,scope:this});this.loaded=true;}}},moveTo:function(bounds,zoomChanged,minor){OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadText();}},parseData:function(ajaxRequest){var text=ajaxRequest.responseText;var options={};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
+var parser=new OpenLayers.Format.Text(options);var features=parser.read(text);for(var i=0,len=features.length;i<len;i++){var data={};var feature=features[i];var location;var iconSize,iconOffset;location=new OpenLayers.LonLat(feature.geometry.x,feature.geometry.y);if(feature.style.graphicWidth&&feature.style.graphicHeight){iconSize=new OpenLayers.Size(feature.style.graphicWidth,feature.style.graphicHeight);}
+if(feature.style.graphicXOffset!==undefined&&feature.style.graphicYOffset!==undefined){iconOffset=new OpenLayers.Pixel(feature.style.graphicXOffset,feature.style.graphicYOffset);}
+if(feature.style.externalGraphic!=null){data.icon=new OpenLayers.Icon(feature.style.externalGraphic,iconSize,iconOffset);}else{data.icon=OpenLayers.Marker.defaultIcon();if(iconSize!=null){data.icon.setSize(iconSize);}}
+if((feature.attributes.title!=null)&&(feature.attributes.description!=null)){data['popupContentHTML']='<h2>'+feature.attributes.title+'</h2>'+'<p>'+feature.attributes.description+'</p>';}
+data['overflow']=feature.attributes.overflow||"auto";var markerFeature=new OpenLayers.Feature(this,location,data);this.features.push(markerFeature);var marker=markerFeature.createMarker();if((feature.attributes.title!=null)&&(feature.attributes.description!=null)){marker.events.register('click',markerFeature,this.markerClick);}
+this.addMarker(marker);}
+this.events.triggerEvent("loadend");},markerClick:function(evt){var sameMarkerClicked=(this==this.layer.selectedFeature);this.layer.selectedFeature=(!sameMarkerClicked)?this:null;for(var i=0,len=this.layer.map.popups.length;i<len;i++){this.layer.map.removePopup(this.layer.map.popups[i]);}
+if(!sameMarkerClicked){this.layer.map.addPopup(this.createPopup());}
+OpenLayers.Event.stop(evt);},clearFeatures:function(){if(this.features!=null){while(this.features.length>0){var feature=this.features[0];OpenLayers.Util.removeItem(this.features,feature);feature.destroy();}}},CLASS_NAME:"OpenLayers.Layer.Text"});OpenLayers.Control.ModifyFeature=OpenLayers.Class(OpenLayers.Control,{geometryTypes:null,clickout:true,toggle:true,standalone:false,layer:null,feature:null,vertices:null,virtualVertices:null,selectControl:null,dragControl:null,handlers:null,deleteCodes:null,virtualStyle:null,mode:null,modified:false,radiusHandle:null,dragHandle:null,onModificationStart:function(){},onModification:function(){},onModificationEnd:function(){},initialize:function(layer,options){this.layer=layer;this.vertices=[];this.virtualVertices=[];this.virtualStyle=OpenLayers.Util.extend({},this.layer.style||this.layer.styleMap.createSymbolizer());this.virtualStyle.fillOpacity=0.3;this.virtualStyle.strokeOpacity=0.3;this.deleteCodes=[46,68];this.mode=OpenLayers.Control.ModifyFeature.RESHAPE;OpenLayers.Control.prototype.initialize.apply(this,[options]);if(!(this.deleteCodes instanceof Array)){this.deleteCodes=[this.deleteCodes];}
+var control=this;var selectOptions={geometryTypes:this.geometryTypes,clickout:this.clickout,toggle:this.toggle,onBeforeSelect:this.beforeSelectFeature,onSelect:this.selectFeature,onUnselect:this.unselectFeature,scope:this};if(this.standalone===false){this.selectControl=new OpenLayers.Control.SelectFeature(layer,selectOptions);}
+var dragOptions={geometryTypes:["OpenLayers.Geometry.Point"],snappingOptions:this.snappingOptions,onStart:function(feature,pixel){control.dragStart.apply(control,[feature,pixel]);},onDrag:function(feature,pixel){control.dragVertex.apply(control,[feature,pixel]);},onComplete:function(feature){control.dragComplete.apply(control,[feature]);},featureCallbacks:{over:function(feature){if(control.standalone!==true||feature._sketch||control.feature===feature){control.dragControl.overFeature.apply(control.dragControl,[feature]);}}}};this.dragControl=new OpenLayers.Control.DragFeature(layer,dragOptions);var keyboardOptions={keydown:this.handleKeypress};this.handlers={keyboard:new OpenLayers.Handler.Keyboard(this,keyboardOptions)};},destroy:function(){this.layer=null;this.standalone||this.selectControl.destroy();this.dragControl.destroy();OpenLayers.Control.prototype.destroy.apply(this,[]);},activate:function(){return((this.standalone||this.selectControl.activate())&&this.handlers.keyboard.activate()&&OpenLayers.Control.prototype.activate.apply(this,arguments));},deactivate:function(){var deactivated=false;if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.layer.removeFeatures(this.vertices,{silent:true});this.layer.removeFeatures(this.virtualVertices,{silent:true});this.vertices=[];this.dragControl.deactivate();var feature=this.feature;var valid=feature&&feature.geometry&&feature.layer;if(this.standalone===false){if(valid){this.selectControl.unselect.apply(this.selectControl,[feature]);}
+this.selectControl.deactivate();}else{if(valid){this.unselectFeature(feature);}}
+this.handlers.keyboard.deactivate();deactivated=true;}
+return deactivated;},beforeSelectFeature:function(feature){return this.layer.events.triggerEvent("beforefeaturemodified",{feature:feature});},selectFeature:function(feature){this.feature=feature;this.modified=false;this.resetVertices();this.dragControl.activate();this.onModificationStart(this.feature);},unselectFeature:function(feature){this.layer.removeFeatures(this.vertices,{silent:true});this.vertices=[];this.layer.destroyFeatures(this.virtualVertices,{silent:true});this.virtualVertices=[];if(this.dragHandle){this.layer.destroyFeatures([this.dragHandle],{silent:true});delete this.dragHandle;}
+if(this.radiusHandle){this.layer.destroyFeatures([this.radiusHandle],{silent:true});delete this.radiusHandle;}
+this.feature=null;this.dragControl.deactivate();this.onModificationEnd(feature);this.layer.events.triggerEvent("afterfeaturemodified",{feature:feature,modified:this.modified});this.modified=false;},dragStart:function(feature,pixel){if(feature!=this.feature&&!feature.geometry.parent&&feature!=this.dragHandle&&feature!=this.radiusHandle){if(this.standalone===false&&this.feature){this.selectControl.clickFeature.apply(this.selectControl,[this.feature]);}
+if(this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)!=-1){this.standalone||this.selectControl.clickFeature.apply(this.selectControl,[feature]);this.dragControl.overFeature.apply(this.dragControl,[feature]);this.dragControl.lastPixel=pixel;this.dragControl.handlers.drag.started=true;this.dragControl.handlers.drag.start=pixel;this.dragControl.handlers.drag.last=pixel;}}},dragVertex:function(vertex,pixel){this.modified=true;if(this.feature.geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){if(this.feature!=vertex){this.feature=vertex;}
+this.layer.events.triggerEvent("vertexmodified",{vertex:vertex.geometry,feature:this.feature,pixel:pixel});}else{if(vertex._index){vertex.geometry.parent.addComponent(vertex.geometry,vertex._index);delete vertex._index;OpenLayers.Util.removeItem(this.virtualVertices,vertex);this.vertices.push(vertex);}else if(vertex==this.dragHandle){this.layer.removeFeatures(this.vertices,{silent:true});this.vertices=[];if(this.radiusHandle){this.layer.destroyFeatures([this.radiusHandle],{silent:true});this.radiusHandle=null;}}else if(vertex!==this.radiusHandle){this.layer.events.triggerEvent("vertexmodified",{vertex:vertex.geometry,feature:this.feature,pixel:pixel});}
+if(this.virtualVertices.length>0){this.layer.destroyFeatures(this.virtualVertices,{silent:true});this.virtualVertices=[];}
+this.layer.drawFeature(this.feature,this.standalone?undefined:this.selectControl.renderIntent);}
+this.layer.drawFeature(vertex);},dragComplete:function(vertex){this.resetVertices();this.setFeatureState();this.onModification(this.feature);this.layer.events.triggerEvent("featuremodified",{feature:this.feature});},setFeatureState:function(){if(this.feature.state!=OpenLayers.State.INSERT&&this.feature.state!=OpenLayers.State.DELETE){this.feature.state=OpenLayers.State.UPDATE;}},resetVertices:function(){if(this.dragControl.feature){this.dragControl.outFeature(this.dragControl.feature);}
+if(this.vertices.length>0){this.layer.removeFeatures(this.vertices,{silent:true});this.vertices=[];}
+if(this.virtualVertices.length>0){this.layer.removeFeatures(this.virtualVertices,{silent:true});this.virtualVertices=[];}
+if(this.dragHandle){this.layer.destroyFeatures([this.dragHandle],{silent:true});this.dragHandle=null;}
+if(this.radiusHandle){this.layer.destroyFeatures([this.radiusHandle],{silent:true});this.radiusHandle=null;}
+if(this.feature&&this.feature.geometry.CLASS_NAME!="OpenLayers.Geometry.Point"){if((this.mode&OpenLayers.Control.ModifyFeature.DRAG)){this.collectDragHandle();}
+if((this.mode&(OpenLayers.Control.ModifyFeature.ROTATE|OpenLayers.Control.ModifyFeature.RESIZE))){this.collectRadiusHandle();}
+if(this.mode&OpenLayers.Control.ModifyFeature.RESHAPE){if(!(this.mode&OpenLayers.Control.ModifyFeature.RESIZE)){this.collectVertices();}}}},handleKeypress:function(evt){var code=evt.keyCode;if(this.feature&&OpenLayers.Util.indexOf(this.deleteCodes,code)!=-1){var vertex=this.dragControl.feature;if(vertex&&OpenLayers.Util.indexOf(this.vertices,vertex)!=-1&&!this.dragControl.handlers.drag.dragging&&vertex.geometry.parent){vertex.geometry.parent.removeComponent(vertex.geometry);this.layer.drawFeature(this.feature,this.standalone?undefined:this.selectControl.renderIntent);this.resetVertices();this.setFeatureState();this.onModification(this.feature);this.layer.events.triggerEvent("featuremodified",{feature:this.feature});}}},collectVertices:function(){this.vertices=[];this.virtualVertices=[];var control=this;function collectComponentVertices(geometry){var i,vertex,component,len;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){vertex=new OpenLayers.Feature.Vector(geometry);vertex._sketch=true;control.vertices.push(vertex);}else{var numVert=geometry.components.length;if(geometry.CLASS_NAME=="OpenLayers.Geometry.LinearRing"){numVert-=1;}
+for(i=0;i<numVert;++i){component=geometry.components[i];if(component.CLASS_NAME=="OpenLayers.Geometry.Point"){vertex=new OpenLayers.Feature.Vector(component);vertex._sketch=true;control.vertices.push(vertex);}else{collectComponentVertices(component);}}
+if(geometry.CLASS_NAME!="OpenLayers.Geometry.MultiPoint"){for(i=0,len=geometry.components.length;i<len-1;++i){var prevVertex=geometry.components[i];var nextVertex=geometry.components[i+1];if(prevVertex.CLASS_NAME=="OpenLayers.Geometry.Point"&&nextVertex.CLASS_NAME=="OpenLayers.Geometry.Point"){var x=(prevVertex.x+nextVertex.x)/2;var y=(prevVertex.y+nextVertex.y)/2;var point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(x,y),null,control.virtualStyle);point.geometry.parent=geometry;point._index=i+1;point._sketch=true;control.virtualVertices.push(point);}}}}}
+collectComponentVertices.call(this,this.feature.geometry);this.layer.addFeatures(this.virtualVertices,{silent:true});this.layer.addFeatures(this.vertices,{silent:true});},collectDragHandle:function(){var geometry=this.feature.geometry;var center=geometry.getBounds().getCenterLonLat();var originGeometry=new OpenLayers.Geometry.Point(center.lon,center.lat);var origin=new OpenLayers.Feature.Vector(originGeometry);originGeometry.move=function(x,y){OpenLayers.Geometry.Point.prototype.move.call(this,x,y);geometry.move(x,y);};origin._sketch=true;this.dragHandle=origin;this.layer.addFeatures([this.dragHandle],{silent:true});},collectRadiusHandle:function(){var geometry=this.feature.geometry;var bounds=geometry.getBounds();var center=bounds.getCenterLonLat();var originGeometry=new OpenLayers.Geometry.Point(center.lon,center.lat);var radiusGeometry=new OpenLayers.Geometry.Point(bounds.right,bounds.bottom);var radius=new OpenLayers.Feature.Vector(radiusGeometry);var resize=(this.mode&OpenLayers.Control.ModifyFeature.RESIZE);var reshape=(this.mode&OpenLayers.Control.ModifyFeature.RESHAPE);var rotate=(this.mode&OpenLayers.Control.ModifyFeature.ROTATE);radiusGeometry.move=function(x,y){OpenLayers.Geometry.Point.prototype.move.call(this,x,y);var dx1=this.x-originGeometry.x;var dy1=this.y-originGeometry.y;var dx0=dx1-x;var dy0=dy1-y;if(rotate){var a0=Math.atan2(dy0,dx0);var a1=Math.atan2(dy1,dx1);var angle=a1-a0;angle*=180/Math.PI;geometry.rotate(angle,originGeometry);}
+if(resize){var scale,ratio;if(reshape){scale=dy1/dy0;ratio=(dx1/dx0)/scale;}else{var l0=Math.sqrt((dx0*dx0)+(dy0*dy0));var l1=Math.sqrt((dx1*dx1)+(dy1*dy1));scale=l1/l0;}
+geometry.resize(scale,originGeometry,ratio);}};radius._sketch=true;this.radiusHandle=radius;this.layer.addFeatures([this.radiusHandle],{silent:true});},setMap:function(map){this.standalone||this.selectControl.setMap(map);this.dragControl.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.ModifyFeature"});OpenLayers.Control.ModifyFeature.RESHAPE=1;OpenLayers.Control.ModifyFeature.RESIZE=2;OpenLayers.Control.ModifyFeature.ROTATE=4;OpenLayers.Control.ModifyFeature.DRAG=8;OpenLayers.Geometry.LineString=OpenLayers.Class(OpenLayers.Geometry.Curve,{initialize:function(points){OpenLayers.Geometry.Curve.prototype.initialize.apply(this,arguments);},removeComponent:function(point){if(this.components&&(this.components.length>2)){OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,arguments);}},intersects:function(geometry){var intersect=false;var type=geometry.CLASS_NAME;if(type=="OpenLayers.Geometry.LineString"||type=="OpenLayers.Geometry.LinearRing"||type=="OpenLayers.Geometry.Point"){var segs1=this.getSortedSegments();var segs2;if(type=="OpenLayers.Geometry.Point"){segs2=[{x1:geometry.x,y1:geometry.y,x2:geometry.x,y2:geometry.y}];}else{segs2=geometry.getSortedSegments();}
+var seg1,seg1x1,seg1x2,seg1y1,seg1y2,seg2,seg2y1,seg2y2;outer:for(var i=0,len=segs1.length;i<len;++i){seg1=segs1[i];seg1x1=seg1.x1;seg1x2=seg1.x2;seg1y1=seg1.y1;seg1y2=seg1.y2;inner:for(var j=0,jlen=segs2.length;j<jlen;++j){seg2=segs2[j];if(seg2.x1>seg1x2){break;}
+if(seg2.x2<seg1x1){continue;}
+seg2y1=seg2.y1;seg2y2=seg2.y2;if(Math.min(seg2y1,seg2y2)>Math.max(seg1y1,seg1y2)){continue;}
+if(Math.max(seg2y1,seg2y2)<Math.min(seg1y1,seg1y2)){continue;}
+if(OpenLayers.Geometry.segmentsIntersect(seg1,seg2)){intersect=true;break outer;}}}}else{intersect=geometry.intersects(this);}
+return intersect;},getSortedSegments:function(){var numSeg=this.components.length-1;var segments=new Array(numSeg),point1,point2;for(var i=0;i<numSeg;++i){point1=this.components[i];point2=this.components[i+1];if(point1.x<point2.x){segments[i]={x1:point1.x,y1:point1.y,x2:point2.x,y2:point2.y};}else{segments[i]={x1:point2.x,y1:point2.y,x2:point1.x,y2:point1.y};}}
+function byX1(seg1,seg2){return seg1.x1-seg2.x1;}
+return segments.sort(byX1);},splitWithSegment:function(seg,options){var edge=!(options&&options.edge===false);var tolerance=options&&options.tolerance;var lines=[];var verts=this.getVertices();var points=[];var intersections=[];var split=false;var vert1,vert2,point;var node,vertex,target;var interOptions={point:true,tolerance:tolerance};var result=null;for(var i=0,stop=verts.length-2;i<=stop;++i){vert1=verts[i];points.push(vert1.clone());vert2=verts[i+1];target={x1:vert1.x,y1:vert1.y,x2:vert2.x,y2:vert2.y};point=OpenLayers.Geometry.segmentsIntersect(seg,target,interOptions);if(point instanceof OpenLayers.Geometry.Point){if((point.x===seg.x1&&point.y===seg.y1)||(point.x===seg.x2&&point.y===seg.y2)||point.equals(vert1)||point.equals(vert2)){vertex=true;}else{vertex=false;}
+if(vertex||edge){if(!point.equals(intersections[intersections.length-1])){intersections.push(point.clone());}
+if(i===0){if(point.equals(vert1)){continue;}}
+if(point.equals(vert2)){continue;}
+split=true;if(!point.equals(vert1)){points.push(point);}
+lines.push(new OpenLayers.Geometry.LineString(points));points=[point.clone()];}}}
+if(split){points.push(vert2.clone());lines.push(new OpenLayers.Geometry.LineString(points));}
+if(intersections.length>0){var xDir=seg.x1<seg.x2?1:-1;var yDir=seg.y1<seg.y2?1:-1;result={lines:lines,points:intersections.sort(function(p1,p2){return(xDir*p1.x-xDir*p2.x)||(yDir*p1.y-yDir*p2.y);})};}
+return result;},split:function(target,options){var results=null;var mutual=options&&options.mutual;var sourceSplit,targetSplit,sourceParts,targetParts;if(target instanceof OpenLayers.Geometry.LineString){var verts=this.getVertices();var vert1,vert2,seg,splits,lines,point;var points=[];sourceParts=[];for(var i=0,stop=verts.length-2;i<=stop;++i){vert1=verts[i];vert2=verts[i+1];seg={x1:vert1.x,y1:vert1.y,x2:vert2.x,y2:vert2.y};targetParts=targetParts||[target];if(mutual){points.push(vert1.clone());}
+for(var j=0;j<targetParts.length;++j){splits=targetParts[j].splitWithSegment(seg,options);if(splits){lines=splits.lines;if(lines.length>0){lines.unshift(j,1);Array.prototype.splice.apply(targetParts,lines);j+=lines.length-2;}
+if(mutual){for(var k=0,len=splits.points.length;k<len;++k){point=splits.points[k];if(!point.equals(vert1)){points.push(point);sourceParts.push(new OpenLayers.Geometry.LineString(points));if(point.equals(vert2)){points=[];}else{points=[point.clone()];}}}}}}}
+if(mutual&&sourceParts.length>0&&points.length>0){points.push(vert2.clone());sourceParts.push(new OpenLayers.Geometry.LineString(points));}}else{results=target.splitWith(this,options);}
+if(targetParts&&targetParts.length>1){targetSplit=true;}else{targetParts=[];}
+if(sourceParts&&sourceParts.length>1){sourceSplit=true;}else{sourceParts=[];}
+if(targetSplit||sourceSplit){if(mutual){results=[sourceParts,targetParts];}else{results=targetParts;}}
+return results;},splitWith:function(geometry,options){return geometry.split(this,options);},getVertices:function(nodes){var vertices;if(nodes===true){vertices=[this.components[0],this.components[this.components.length-1]];}else if(nodes===false){vertices=this.components.slice(1,this.components.length-1);}else{vertices=this.components.slice();}
+return vertices;},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var details=edge&&options&&options.details;var result,best={};var min=Number.POSITIVE_INFINITY;if(geometry instanceof OpenLayers.Geometry.Point){var segs=this.getSortedSegments();var x=geometry.x;var y=geometry.y;var seg;for(var i=0,len=segs.length;i<len;++i){seg=segs[i];result=OpenLayers.Geometry.distanceToSegment(geometry,seg);if(result.distance<min){min=result.distance;best=result;if(min===0){break;}}else{if(seg.x2>x&&((y>seg.y1&&y<seg.y2)||(y<seg.y1&&y>seg.y2))){break;}}}
+if(details){best={distance:best.distance,x0:best.x,y0:best.y,x1:x,y1:y};}else{best=best.distance;}}else if(geometry instanceof OpenLayers.Geometry.LineString){var segs0=this.getSortedSegments();var segs1=geometry.getSortedSegments();var seg0,seg1,intersection,x0,y0;var len1=segs1.length;var interOptions={point:true};outer:for(var i=0,len=segs0.length;i<len;++i){seg0=segs0[i];x0=seg0.x1;y0=seg0.y1;for(var j=0;j<len1;++j){seg1=segs1[j];intersection=OpenLayers.Geometry.segmentsIntersect(seg0,seg1,interOptions);if(intersection){min=0;best={distance:0,x0:intersection.x,y0:intersection.y,x1:intersection.x,y1:intersection.y};break outer;}else{result=OpenLayers.Geometry.distanceToSegment({x:x0,y:y0},seg1);if(result.distance<min){min=result.distance;best={distance:min,x0:x0,y0:y0,x1:result.x,y1:result.y};}}}}
+if(!details){best=best.distance;}
+if(min!==0){if(seg0){result=geometry.distanceTo(new OpenLayers.Geometry.Point(seg0.x2,seg0.y2),options);var dist=details?result.distance:result;if(dist<min){if(details){best={distance:min,x0:result.x1,y0:result.y1,x1:result.x0,y1:result.y0};}else{best=dist;}}}}}else{best=geometry.distanceTo(this,options);if(details){best={distance:best.distance,x0:best.x1,y0:best.y1,x1:best.x0,y1:best.y0};}}
+return best;},CLASS_NAME:"OpenLayers.Geometry.LineString"});OpenLayers.Control.TransformFeature=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforesetfeature","setfeature","beforetransform","transform","transformcomplete"],geometryTypes:null,layer:null,preserveAspectRatio:false,rotate:true,feature:null,renderIntent:"temporary",rotationHandleSymbolizer:null,box:null,center:null,scale:1,ratio:1,rotation:0,handles:null,rotationHandles:null,dragControl:null,initialize:function(layer,options){this.EVENT_TYPES=OpenLayers.Control.TransformFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.layer=layer;if(!this.rotationHandleSymbolizer){this.rotationHandleSymbolizer={stroke:false,pointRadius:10,fillOpacity:0,cursor:"pointer"};}
+this.createBox();this.createControl();},activate:function(){var activated=false;if(OpenLayers.Control.prototype.activate.apply(this,arguments)){this.dragControl.activate();this.layer.addFeatures([this.box]);this.rotate&&this.layer.addFeatures(this.rotationHandles);this.layer.addFeatures(this.handles);activated=true;}
+return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.layer.removeFeatures(this.handles);this.rotate&&this.layer.removeFeatures(this.rotationHandles);this.layer.removeFeatures([this.box]);this.dragControl.deactivate();deactivated=true;}
+return deactivated;},setMap:function(map){this.dragControl.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},setFeature:function(feature,initialParams){initialParams=OpenLayers.Util.applyDefaults(initialParams,{rotation:0,scale:1,ratio:1});var evt={feature:feature};var oldRotation=this.rotation;var oldCenter=this.center;OpenLayers.Util.extend(this,initialParams);if(this.events.triggerEvent("beforesetfeature",evt)===false){return;}
+this.feature=feature;this.activate();this._setfeature=true;var featureBounds=this.feature.geometry.getBounds();this.box.move(featureBounds.getCenterLonLat());this.box.geometry.rotate(-oldRotation,oldCenter);this._angle=0;var ll;if(this.rotation){var geom=feature.geometry.clone();geom.rotate(-this.rotation,this.center);var box=new OpenLayers.Feature.Vector(geom.getBounds().toGeometry());box.geometry.rotate(this.rotation,this.center);this.box.geometry.rotate(this.rotation,this.center);this.box.move(box.geometry.getBounds().getCenterLonLat());var llGeom=box.geometry.components[0].components[0];ll=llGeom.getBounds().getCenterLonLat();}else{ll=new OpenLayers.LonLat(featureBounds.left,featureBounds.bottom);}
+this.handles[0].move(ll);delete this._setfeature;this.events.triggerEvent("setfeature",evt);},createBox:function(){var control=this;this.center=new OpenLayers.Geometry.Point(0,0);var box=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([new OpenLayers.Geometry.Point(-1,-1),new OpenLayers.Geometry.Point(0,-1),new OpenLayers.Geometry.Point(1,-1),new OpenLayers.Geometry.Point(1,0),new OpenLayers.Geometry.Point(1,1),new OpenLayers.Geometry.Point(0,1),new OpenLayers.Geometry.Point(-1,1),new OpenLayers.Geometry.Point(-1,0),new OpenLayers.Geometry.Point(-1,-1)]),null,typeof this.renderIntent=="string"?null:this.renderIntent);box.geometry.move=function(x,y){control._moving=true;OpenLayers.Geometry.LineString.prototype.move.apply(this,arguments);control.center.move(x,y);delete control._moving;};var vertexMoveFn=function(x,y){OpenLayers.Geometry.Point.prototype.move.apply(this,arguments);this._rotationHandle&&this._rotationHandle.geometry.move(x,y);this._handle.geometry.move(x,y);};var vertexResizeFn=function(scale,center,ratio){OpenLayers.Geometry.Point.prototype.resize.apply(this,arguments);this._rotationHandle&&this._rotationHandle.geometry.resize(scale,center,ratio);this._handle.geometry.resize(scale,center,ratio);};var vertexRotateFn=function(angle,center){OpenLayers.Geometry.Point.prototype.rotate.apply(this,arguments);this._rotationHandle&&this._rotationHandle.geometry.rotate(angle,center);this._handle.geometry.rotate(angle,center);};var handleMoveFn=function(x,y){var oldX=this.x,oldY=this.y;OpenLayers.Geometry.Point.prototype.move.call(this,x,y);if(control._moving){return;}
+var evt=control.dragControl.handlers.drag.evt;var preserveAspectRatio=!control._setfeature&&control.preserveAspectRatio;var reshape=!preserveAspectRatio&&!(evt&&evt.shiftKey);var oldGeom=new OpenLayers.Geometry.Point(oldX,oldY);var centerGeometry=control.center;this.rotate(-control.rotation,centerGeometry);oldGeom.rotate(-control.rotation,centerGeometry);var dx1=this.x-centerGeometry.x;var dy1=this.y-centerGeometry.y;var dx0=dx1-(this.x-oldGeom.x);var dy0=dy1-(this.y-oldGeom.y);this.x=oldX;this.y=oldY;var scale,ratio=1;if(reshape){scale=Math.abs(dy0)<0.00001?1:dy1/dy0;ratio=(Math.abs(dx0)<0.00001?1:(dx1/dx0))/scale;}else{var l0=Math.sqrt((dx0*dx0)+(dy0*dy0));var l1=Math.sqrt((dx1*dx1)+(dy1*dy1));scale=l1/l0;}
+control._moving=true;control.box.geometry.rotate(-control.rotation,centerGeometry);delete control._moving;control.box.geometry.resize(scale,centerGeometry,ratio);control.box.geometry.rotate(control.rotation,centerGeometry);control.transformFeature({scale:scale,ratio:ratio});};var rotationHandleMoveFn=function(x,y){var oldX=this.x,oldY=this.y;OpenLayers.Geometry.Point.prototype.move.call(this,x,y);if(control._moving){return;}
+var evt=control.dragControl.handlers.drag.evt;var constrain=(evt&&evt.shiftKey)?45:1;var centerGeometry=control.center;var dx1=this.x-centerGeometry.x;var dy1=this.y-centerGeometry.y;var dx0=dx1-x;var dy0=dy1-y;this.x=oldX;this.y=oldY;var a0=Math.atan2(dy0,dx0);var a1=Math.atan2(dy1,dx1);var angle=a1-a0;angle*=180/Math.PI;control._angle=(control._angle+angle)%360;var diff=control.rotation%constrain;if(Math.abs(control._angle)>=constrain||diff!==0){angle=Math.round(control._angle/constrain)*constrain-
+diff;control._angle=0;control.box.geometry.rotate(angle,centerGeometry);control.transformFeature({rotation:angle});}};var handles=new Array(8);var rotationHandles=new Array(4);var geom,handle,rotationHandle;for(var i=0;i<8;++i){geom=box.geometry.components[i];handle=new OpenLayers.Feature.Vector(geom.clone(),null,typeof this.renderIntent=="string"?null:this.renderIntent);if(i%2==0){rotationHandle=new OpenLayers.Feature.Vector(geom.clone(),null,typeof this.rotationHandleSymbolizer=="string"?null:this.rotationHandleSymbolizer);rotationHandle.geometry.move=rotationHandleMoveFn;geom._rotationHandle=rotationHandle;rotationHandles[i/2]=rotationHandle;}
+geom.move=vertexMoveFn;geom.resize=vertexResizeFn;geom.rotate=vertexRotateFn;handle.geometry.move=handleMoveFn;geom._handle=handle;handles[i]=handle;}
+this.box=box;this.rotationHandles=rotationHandles;this.handles=handles;},createControl:function(){var control=this;this.dragControl=new OpenLayers.Control.DragFeature(this.layer,{documentDrag:true,moveFeature:function(pixel){if(this.feature===control.feature){this.feature=control.box;}
+OpenLayers.Control.DragFeature.prototype.moveFeature.apply(this,arguments);},onDrag:function(feature,pixel){if(feature===control.box){control.transformFeature({center:control.center});control.drawHandles();}},onStart:function(feature,pixel){var eligible=!control.geometryTypes||OpenLayers.Util.indexOf(control.geometryTypes,feature.geometry.CLASS_NAME)!==-1;var i=OpenLayers.Util.indexOf(control.handles,feature);i+=OpenLayers.Util.indexOf(control.rotationHandles,feature);if(feature!==control.feature&&feature!==control.box&&i==-2&&eligible){control.setFeature(feature);}},onComplete:function(feature,pixel){control.events.triggerEvent("transformcomplete",{feature:control.feature});}});},drawHandles:function(){var layer=this.layer;for(var i=0;i<8;++i){if(this.rotate&&i%2===0){layer.drawFeature(this.rotationHandles[i/2],this.rotationHandleSymbolizer);}
+layer.drawFeature(this.handles[i],this.renderIntent);}},transformFeature:function(mods){if(!this._setfeature){this.scale*=(mods.scale||1);this.ratio*=(mods.ratio||1);var oldRotation=this.rotation;this.rotation=(this.rotation+(mods.rotation||0))%360;if(this.events.triggerEvent("beforetransform",mods)!==false){var feature=this.feature;var geom=feature.geometry;var center=this.center;geom.rotate(-oldRotation,center);if(mods.scale||mods.ratio){geom.resize(mods.scale,center,mods.ratio);}else if(mods.center){feature.move(mods.center.getBounds().getCenterLonLat());}
+geom.rotate(this.rotation,center);this.layer.drawFeature(feature);feature.toState(OpenLayers.State.UPDATE);this.events.triggerEvent("transform",mods);}}
+this.layer.drawFeature(this.box,this.renderIntent);this.drawHandles();},destroy:function(){var geom;for(var i=0;i<8;++i){geom=this.box.geometry.components[i];geom._handle.destroy();geom._handle=null;geom._rotationHandle&&geom._rotationHandle.destroy();geom._rotationHandle=null;}
+this.box.destroy();this.box=null;this.layer=null;this.dragControl.destroy();OpenLayers.Control.prototype.destroy.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.TransformFeature"});OpenLayers.Format.GPX=OpenLayers.Class(OpenLayers.Format.XML,{extractWaypoints:true,extractTracks:true,extractRoutes:true,extractAttributes:true,initialize:function(options){this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
+var features=[];if(this.extractTracks){var tracks=doc.getElementsByTagName("trk");for(var i=0,len=tracks.length;i<len;i++){var attrs={};if(this.extractAttributes){attrs=this.parseAttributes(tracks[i]);}
+var segs=this.getElementsByTagNameNS(tracks[i],tracks[i].namespaceURI,"trkseg");for(var j=0,seglen=segs.length;j<seglen;j++){var track=this.extractSegment(segs[j],"trkpt");features.push(new OpenLayers.Feature.Vector(track,attrs));}}}
+if(this.extractRoutes){var routes=doc.getElementsByTagName("rte");for(var k=0,klen=routes.length;k<klen;k++){var attrs={};if(this.extractAttributes){attrs=this.parseAttributes(routes[k]);}
+var route=this.extractSegment(routes[k],"rtept");features.push(new OpenLayers.Feature.Vector(route,attrs));}}
+if(this.extractWaypoints){var waypoints=doc.getElementsByTagName("wpt");for(var l=0,len=waypoints.length;l<len;l++){var attrs={};if(this.extractAttributes){attrs=this.parseAttributes(waypoints[l]);}
+var wpt=new OpenLayers.Geometry.Point(waypoints[l].getAttribute("lon"),waypoints[l].getAttribute("lat"));features.push(new OpenLayers.Feature.Vector(wpt,attrs));}}
+if(this.internalProjection&&this.externalProjection){for(var g=0,featLength=features.length;g<featLength;g++){features[g].geometry.transform(this.externalProjection,this.internalProjection);}}
+return features;},extractSegment:function(segment,segmentType){var points=this.getElementsByTagNameNS(segment,segment.namespaceURI,segmentType);var point_features=[];for(var i=0,len=points.length;i<len;i++){point_features.push(new OpenLayers.Geometry.Point(points[i].getAttribute("lon"),points[i].getAttribute("lat")));}
+return new OpenLayers.Geometry.LineString(point_features);},parseAttributes:function(node){var attributes={};var attrNode=node.firstChild;while(attrNode){if(attrNode.nodeType==1){var value=attrNode.firstChild;if(value.nodeType==3||value.nodeType==4){name=(attrNode.prefix)?attrNode.nodeName.split(":")[1]:attrNode.nodeName;if(name!="trkseg"&&name!="rtept"){attributes[name]=value.nodeValue;}}}
+attrNode=attrNode.nextSibling;}
+return attributes;},CLASS_NAME:"OpenLayers.Format.GPX"});OpenLayers.Geometry.LinearRing=OpenLayers.Class(OpenLayers.Geometry.LineString,{componentTypes:["OpenLayers.Geometry.Point"],initialize:function(points){OpenLayers.Geometry.LineString.prototype.initialize.apply(this,arguments);},addComponent:function(point,index){var added=false;var lastPoint=this.components.pop();if(index!=null||!point.equals(lastPoint)){added=OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,arguments);}
+var firstPoint=this.components[0];OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,[firstPoint]);return added;},removeComponent:function(point){if(this.components.length>4){this.components.pop();OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,arguments);var firstPoint=this.components[0];OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,[firstPoint]);}},move:function(x,y){for(var i=0,len=this.components.length;i<len-1;i++){this.components[i].move(x,y);}},rotate:function(angle,origin){for(var i=0,len=this.components.length;i<len-1;++i){this.components[i].rotate(angle,origin);}},resize:function(scale,origin,ratio){for(var i=0,len=this.components.length;i<len-1;++i){this.components[i].resize(scale,origin,ratio);}
+return this;},transform:function(source,dest){if(source&&dest){for(var i=0,len=this.components.length;i<len-1;i++){var component=this.components[i];component.transform(source,dest);}
+this.bounds=null;}
+return this;},getCentroid:function(){if(this.components&&(this.components.length>2)){var sumX=0.0;var sumY=0.0;for(var i=0;i<this.components.length-1;i++){var b=this.components[i];var c=this.components[i+1];sumX+=(b.x+c.x)*(b.x*c.y-c.x*b.y);sumY+=(b.y+c.y)*(b.x*c.y-c.x*b.y);}
+var area=-1*this.getArea();var x=sumX/(6*area);var y=sumY/(6*area);return new OpenLayers.Geometry.Point(x,y);}else{return null;}},getArea:function(){var area=0.0;if(this.components&&(this.components.length>2)){var sum=0.0;for(var i=0,len=this.components.length;i<len-1;i++){var b=this.components[i];var c=this.components[i+1];sum+=(b.x+c.x)*(c.y-b.y);}
+area=-sum/2.0;}
+return area;},getGeodesicArea:function(projection){var ring=this;if(projection){var gg=new OpenLayers.Projection("EPSG:4326");if(!gg.equals(projection)){ring=this.clone().transform(projection,gg);}}
+var area=0.0;var len=ring.components&&ring.components.length;if(len>2){var p1,p2;for(var i=0;i<len-1;i++){p1=ring.components[i];p2=ring.components[i+1];area+=OpenLayers.Util.rad(p2.x-p1.x)*(2+Math.sin(OpenLayers.Util.rad(p1.y))+
+Math.sin(OpenLayers.Util.rad(p2.y)));}
+area=area*6378137.0*6378137.0/2.0;}
+return area;},containsPoint:function(point){var approx=OpenLayers.Number.limitSigDigs;var digs=14;var px=approx(point.x,digs);var py=approx(point.y,digs);function getX(y,x1,y1,x2,y2){return(((x1-x2)*y)+((x2*y1)-(x1*y2)))/(y1-y2);}
+var numSeg=this.components.length-1;var start,end,x1,y1,x2,y2,cx,cy;var crosses=0;for(var i=0;i<numSeg;++i){start=this.components[i];x1=approx(start.x,digs);y1=approx(start.y,digs);end=this.components[i+1];x2=approx(end.x,digs);y2=approx(end.y,digs);if(y1==y2){if(py==y1){if(x1<=x2&&(px>=x1&&px<=x2)||x1>=x2&&(px<=x1&&px>=x2)){crosses=-1;break;}}
+continue;}
+cx=approx(getX(py,x1,y1,x2,y2),digs);if(cx==px){if(y1<y2&&(py>=y1&&py<=y2)||y1>y2&&(py<=y1&&py>=y2)){crosses=-1;break;}}
+if(cx<=px){continue;}
+if(x1!=x2&&(cx<Math.min(x1,x2)||cx>Math.max(x1,x2))){continue;}
+if(y1<y2&&(py>=y1&&py<y2)||y1>y2&&(py<y1&&py>=y2)){++crosses;}}
+var contained=(crosses==-1)?1:!!(crosses&1);return contained;},intersects:function(geometry){var intersect=false;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){intersect=this.containsPoint(geometry);}else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LineString"){intersect=geometry.intersects(this);}else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LinearRing"){intersect=OpenLayers.Geometry.LineString.prototype.intersects.apply(this,[geometry]);}else{for(var i=0,len=geometry.components.length;i<len;++i){intersect=geometry.components[i].intersects(this);if(intersect){break;}}}
+return intersect;},getVertices:function(nodes){return(nodes===true)?[]:this.components.slice(0,this.components.length-1);},CLASS_NAME:"OpenLayers.Geometry.LinearRing"});OpenLayers.Geometry.MultiLineString=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.LineString"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},split:function(geometry,options){var results=null;var mutual=options&&options.mutual;var splits,sourceLine,sourceLines,sourceSplit,targetSplit;var sourceParts=[];var targetParts=[geometry];for(var i=0,len=this.components.length;i<len;++i){sourceLine=this.components[i];sourceSplit=false;for(var j=0;j<targetParts.length;++j){splits=sourceLine.split(targetParts[j],options);if(splits){if(mutual){sourceLines=splits[0];for(var k=0,klen=sourceLines.length;k<klen;++k){if(k===0&&sourceParts.length){sourceParts[sourceParts.length-1].addComponent(sourceLines[k]);}else{sourceParts.push(new OpenLayers.Geometry.MultiLineString([sourceLines[k]]));}}
+sourceSplit=true;splits=splits[1];}
+if(splits.length){splits.unshift(j,1);Array.prototype.splice.apply(targetParts,splits);break;}}}
+if(!sourceSplit){if(sourceParts.length){sourceParts[sourceParts.length-1].addComponent(sourceLine.clone());}else{sourceParts=[new OpenLayers.Geometry.MultiLineString(sourceLine.clone())];}}}
+if(sourceParts&&sourceParts.length>1){sourceSplit=true;}else{sourceParts=[];}
+if(targetParts&&targetParts.length>1){targetSplit=true;}else{targetParts=[];}
+if(sourceSplit||targetSplit){if(mutual){results=[sourceParts,targetParts];}else{results=targetParts;}}
+return results;},splitWith:function(geometry,options){var results=null;var mutual=options&&options.mutual;var splits,targetLine,sourceLines,sourceSplit,targetSplit,sourceParts,targetParts;if(geometry instanceof OpenLayers.Geometry.LineString){targetParts=[];sourceParts=[geometry];for(var i=0,len=this.components.length;i<len;++i){targetSplit=false;targetLine=this.components[i];for(var j=0;j<sourceParts.length;++j){splits=sourceParts[j].split(targetLine,options);if(splits){if(mutual){sourceLines=splits[0];if(sourceLines.length){sourceLines.unshift(j,1);Array.prototype.splice.apply(sourceParts,sourceLines);j+=sourceLines.length-2;}
+splits=splits[1];if(splits.length===0){splits=[targetLine.clone()];}}
+for(var k=0,klen=splits.length;k<klen;++k){if(k===0&&targetParts.length){targetParts[targetParts.length-1].addComponent(splits[k]);}else{targetParts.push(new OpenLayers.Geometry.MultiLineString([splits[k]]));}}
+targetSplit=true;}}
+if(!targetSplit){if(targetParts.length){targetParts[targetParts.length-1].addComponent(targetLine.clone());}else{targetParts=[new OpenLayers.Geometry.MultiLineString([targetLine.clone()])];}}}}else{results=geometry.split(this);}
+if(sourceParts&&sourceParts.length>1){sourceSplit=true;}else{sourceParts=[];}
+if(targetParts&&targetParts.length>1){targetSplit=true;}else{targetParts=[];}
+if(sourceSplit||targetSplit){if(mutual){results=[sourceParts,targetParts];}else{results=targetParts;}}
+return results;},CLASS_NAME:"OpenLayers.Geometry.MultiLineString"});OpenLayers.Handler.Path=OpenLayers.Class(OpenLayers.Handler.Point,{line:null,freehand:false,freehandToggle:'shiftKey',initialize:function(control,callbacks,options){OpenLayers.Handler.Point.prototype.initialize.apply(this,arguments);},createFeature:function(pixel){var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.line=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([this.point.geometry]));this.callback("create",[this.point.geometry,this.getSketch()]);this.point.geometry.clearBounds();this.layer.addFeatures([this.line,this.point],{silent:true});},destroyFeature:function(){OpenLayers.Handler.Point.prototype.destroyFeature.apply(this);this.line=null;},removePoint:function(){if(this.point){this.layer.removeFeatures([this.point]);}},addPoint:function(pixel){this.layer.removeFeatures([this.point]);var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.line.geometry.addComponent(this.point.geometry,this.line.geometry.components.length);this.callback("point",[this.point.geometry,this.getGeometry()]);this.callback("modify",[this.point.geometry,this.getSketch()]);this.drawFeature();},freehandMode:function(evt){return(this.freehandToggle&&evt[this.freehandToggle])?!this.freehand:this.freehand;},modifyFeature:function(pixel){var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point.geometry.x=lonlat.lon;this.point.geometry.y=lonlat.lat;this.callback("modify",[this.point.geometry,this.getSketch()]);this.point.geometry.clearBounds();this.drawFeature();},drawFeature:function(){this.layer.drawFeature(this.line,this.style);this.layer.drawFeature(this.point,this.style);},getSketch:function(){return this.line;},getGeometry:function(){var geometry=this.line&&this.line.geometry;if(geometry&&this.multi){geometry=new OpenLayers.Geometry.MultiLineString([geometry]);}
+return geometry;},mousedown:function(evt){if(this.lastDown&&this.lastDown.equals(evt.xy)){return false;}
+if(this.lastDown==null){if(this.persist){this.destroyFeature();}
+this.createFeature(evt.xy);}else if((this.lastUp==null)||!this.lastUp.equals(evt.xy)){this.addPoint(evt.xy);}
+this.mouseDown=true;this.lastDown=evt.xy;this.drawing=true;return false;},mousemove:function(evt){if(this.drawing){if(this.mouseDown&&this.freehandMode(evt)){this.addPoint(evt.xy);}else{this.modifyFeature(evt.xy);}}
+return true;},mouseup:function(evt){this.mouseDown=false;if(this.drawing){if(this.freehandMode(evt)){this.removePoint();this.finalize();}else{if(this.lastUp==null){this.addPoint(evt.xy);}
+this.lastUp=evt.xy;}
+return false;}
+return true;},dblclick:function(evt){if(!this.freehandMode(evt)){var index=this.line.geometry.components.length-1;this.line.geometry.removeComponent(this.line.geometry.components[index]);this.removePoint();this.finalize();}
+return false;},CLASS_NAME:"OpenLayers.Handler.Path"});OpenLayers.Control.Split=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforesplit","split","aftersplit"],layer:null,source:null,sourceOptions:null,tolerance:null,edge:true,deferDelete:false,mutual:true,targetFilter:null,sourceFilter:null,handler:null,initialize:function(options){Array.prototype.push.apply(this.EVENT_TYPES,OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.options=options||{};if(this.options.source){this.setSource(this.options.source);}},setSource:function(layer){if(this.active){this.deactivate();if(this.handler){this.handler.destroy();delete this.handler;}
+this.source=layer;this.activate();}else{this.source=layer;}},activate:function(){var activated=OpenLayers.Control.prototype.activate.call(this);if(activated){if(!this.source){if(!this.handler){this.handler=new OpenLayers.Handler.Path(this,{done:function(geometry){this.onSketchComplete({feature:new OpenLayers.Feature.Vector(geometry)});}},{layerOptions:this.sourceOptions});}
+this.handler.activate();}else if(this.source.events){this.source.events.on({sketchcomplete:this.onSketchComplete,afterfeaturemodified:this.afterFeatureModified,scope:this});}}
+return activated;},deactivate:function(){var deactivated=OpenLayers.Control.prototype.deactivate.call(this);if(deactivated){if(this.source&&this.source.events){this.layer.events.un({sketchcomplete:this.onSketchComplete,afterfeaturemodified:this.afterFeatureModified,scope:this});}}
+return deactivated;},onSketchComplete:function(event){this.feature=null;return!this.considerSplit(event.feature);},afterFeatureModified:function(event){if(event.modified){var feature=event.feature;if(feature.geometry instanceof OpenLayers.Geometry.LineString||feature.geometry instanceof OpenLayers.Geometry.MultiLineString){this.feature=event.feature;this.considerSplit(event.feature);}}},removeByGeometry:function(features,geometry){for(var i=0,len=features.length;i<len;++i){if(features[i].geometry===geometry){features.splice(i,1);break;}}},isEligible:function(target){return(target.state!==OpenLayers.State.DELETE)&&(target.geometry instanceof OpenLayers.Geometry.LineString||target.geometry instanceof OpenLayers.Geometry.MultiLineString)&&(this.feature!==target)&&(!this.targetFilter||this.targetFilter.evaluate(target.attributes));},considerSplit:function(feature){var sourceSplit=false;var targetSplit=false;if(!this.sourceFilter||this.sourceFilter.evaluate(feature.attributes)){var features=this.layer&&this.layer.features||[];var target,results,proceed;var additions=[],removals=[];var mutual=(this.layer===this.source)&&this.mutual;var options={edge:this.edge,tolerance:this.tolerance,mutual:mutual};var sourceParts=[feature.geometry];var targetFeature,targetParts;var source,parts;for(var i=0,len=features.length;i<len;++i){targetFeature=features[i];if(this.isEligible(targetFeature)){targetParts=[targetFeature.geometry];for(var j=0;j<sourceParts.length;++j){source=sourceParts[j];for(var k=0;k<targetParts.length;++k){target=targetParts[k];if(source.getBounds().intersectsBounds(target.getBounds())){results=source.split(target,options);if(results){proceed=this.events.triggerEvent("beforesplit",{source:feature,target:targetFeature});if(proceed!==false){if(mutual){parts=results[0];if(parts.length>1){parts.unshift(j,1);Array.prototype.splice.apply(sourceParts,parts);j+=parts.length-3;}
+results=results[1];}
+if(results.length>1){results.unshift(k,1);Array.prototype.splice.apply(targetParts,results);k+=results.length-3;}}}}}}
+if(targetParts&&targetParts.length>1){this.geomsToFeatures(targetFeature,targetParts);this.events.triggerEvent("split",{original:targetFeature,features:targetParts});Array.prototype.push.apply(additions,targetParts);removals.push(targetFeature);targetSplit=true;}}}
+if(sourceParts&&sourceParts.length>1){this.geomsToFeatures(feature,sourceParts);this.events.triggerEvent("split",{original:feature,features:sourceParts});Array.prototype.push.apply(additions,sourceParts);removals.push(feature);sourceSplit=true;}
+if(sourceSplit||targetSplit){if(this.deferDelete){var feat,destroys=[];for(var i=0,len=removals.length;i<len;++i){feat=removals[i];if(feat.state===OpenLayers.State.INSERT){destroys.push(feat);}else{feat.state=OpenLayers.State.DELETE;this.layer.drawFeature(feat);}}
+this.layer.destroyFeatures(destroys,{silent:true});for(var i=0,len=additions.length;i<len;++i){additions[i].state=OpenLayers.State.INSERT;}}else{this.layer.destroyFeatures(removals,{silent:true});}
+this.layer.addFeatures(additions,{silent:true});this.events.triggerEvent("aftersplit",{source:feature,features:additions});}}
+return sourceSplit;},geomsToFeatures:function(feature,geoms){var clone=feature.clone();delete clone.geometry;var newFeature;for(var i=0,len=geoms.length;i<len;++i){newFeature=clone.clone();newFeature.geometry=geoms[i];newFeature.state=OpenLayers.State.INSERT;geoms[i]=newFeature;}},destroy:function(){if(this.active){this.deactivate();}
+OpenLayers.Control.prototype.destroy.call(this);},CLASS_NAME:"OpenLayers.Control.Split"});OpenLayers.Geometry.Polygon=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.LinearRing"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},getArea:function(){var area=0.0;if(this.components&&(this.components.length>0)){area+=Math.abs(this.components[0].getArea());for(var i=1,len=this.components.length;i<len;i++){area-=Math.abs(this.components[i].getArea());}}
+return area;},getGeodesicArea:function(projection){var area=0.0;if(this.components&&(this.components.length>0)){area+=Math.abs(this.components[0].getGeodesicArea(projection));for(var i=1,len=this.components.length;i<len;i++){area-=Math.abs(this.components[i].getGeodesicArea(projection));}}
+return area;},containsPoint:function(point){var numRings=this.components.length;var contained=false;if(numRings>0){contained=this.components[0].containsPoint(point);if(contained!==1){if(contained&&numRings>1){var hole;for(var i=1;i<numRings;++i){hole=this.components[i].containsPoint(point);if(hole){if(hole===1){contained=1;}else{contained=false;}
+break;}}}}}
+return contained;},intersects:function(geometry){var intersect=false;var i,len;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){intersect=this.containsPoint(geometry);}else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LineString"||geometry.CLASS_NAME=="OpenLayers.Geometry.LinearRing"){for(i=0,len=this.components.length;i<len;++i){intersect=geometry.intersects(this.components[i]);if(intersect){break;}}
+if(!intersect){for(i=0,len=geometry.components.length;i<len;++i){intersect=this.containsPoint(geometry.components[i]);if(intersect){break;}}}}else{for(i=0,len=geometry.components.length;i<len;++i){intersect=this.intersects(geometry.components[i]);if(intersect){break;}}}
+if(!intersect&&geometry.CLASS_NAME=="OpenLayers.Geometry.Polygon"){var ring=this.components[0];for(i=0,len=ring.components.length;i<len;++i){intersect=geometry.containsPoint(ring.components[i]);if(intersect){break;}}}
+return intersect;},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var result;if(!edge&&this.intersects(geometry)){result=0;}else{result=OpenLayers.Geometry.Collection.prototype.distanceTo.apply(this,[geometry,options]);}
+return result;},CLASS_NAME:"OpenLayers.Geometry.Polygon"});OpenLayers.Geometry.Polygon.createRegularPolygon=function(origin,radius,sides,rotation){var angle=Math.PI*((1/sides)-(1/2));if(rotation){angle+=(rotation/180)*Math.PI;}
+var rotatedAngle,x,y;var points=[];for(var i=0;i<sides;++i){rotatedAngle=angle+(i*2*Math.PI/sides);x=origin.x+(radius*Math.cos(rotatedAngle));y=origin.y+(radius*Math.sin(rotatedAngle));points.push(new OpenLayers.Geometry.Point(x,y));}
+var ring=new OpenLayers.Geometry.LinearRing(points);return new OpenLayers.Geometry.Polygon([ring]);};OpenLayers.Format.GeoRSS=OpenLayers.Class(OpenLayers.Format.XML,{rssns:"http://backend.userland.com/rss2",featureNS:"http://mapserver.gis.umn.edu/mapserver",georssns:"http://www.georss.org/georss",geons:"http://www.w3.org/2003/01/geo/wgs84_pos#",featureTitle:"Untitled",featureDescription:"No Description",gmlParser:null,xy:false,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},createGeometryFromItem:function(item){var point=this.getElementsByTagNameNS(item,this.georssns,"point");var lat=this.getElementsByTagNameNS(item,this.geons,'lat');var lon=this.getElementsByTagNameNS(item,this.geons,'long');var line=this.getElementsByTagNameNS(item,this.georssns,"line");var polygon=this.getElementsByTagNameNS(item,this.georssns,"polygon");var where=this.getElementsByTagNameNS(item,this.georssns,"where");var box=this.getElementsByTagNameNS(item,this.georssns,"box");if(point.length>0||(lat.length>0&&lon.length>0)){var location;if(point.length>0){location=OpenLayers.String.trim(point[0].firstChild.nodeValue).split(/\s+/);if(location.length!=2){location=OpenLayers.String.trim(point[0].firstChild.nodeValue).split(/\s*,\s*/);}}else{location=[parseFloat(lat[0].firstChild.nodeValue),parseFloat(lon[0].firstChild.nodeValue)];}
+var geometry=new OpenLayers.Geometry.Point(parseFloat(location[1]),parseFloat(location[0]));}else if(line.length>0){var coords=OpenLayers.String.trim(this.concatChildValues(line[0])).split(/\s+/);var components=[];var point;for(var i=0,len=coords.length;i<len;i+=2){point=new OpenLayers.Geometry.Point(parseFloat(coords[i+1]),parseFloat(coords[i]));components.push(point);}
+geometry=new OpenLayers.Geometry.LineString(components);}else if(polygon.length>0){var coords=OpenLayers.String.trim(this.concatChildValues(polygon[0])).split(/\s+/);var components=[];var point;for(var i=0,len=coords.length;i<len;i+=2){point=new OpenLayers.Geometry.Point(parseFloat(coords[i+1]),parseFloat(coords[i]));components.push(point);}
+geometry=new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]);}else if(where.length>0){if(!this.gmlParser){this.gmlParser=new OpenLayers.Format.GML({'xy':this.xy});}
+var feature=this.gmlParser.parseFeature(where[0]);geometry=feature.geometry;}else if(box.length>0){var coords=OpenLayers.String.trim(box[0].firstChild.nodeValue).split(/\s+/);var components=[];var point;if(coords.length>3){point=new OpenLayers.Geometry.Point(parseFloat(coords[1]),parseFloat(coords[0]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[1]),parseFloat(coords[2]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[3]),parseFloat(coords[2]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[3]),parseFloat(coords[0]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[1]),parseFloat(coords[0]));components.push(point);}
+geometry=new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]);}
+if(geometry&&this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}
+return geometry;},createFeatureFromItem:function(item){var geometry=this.createGeometryFromItem(item);var title=this.getChildValue(item,"*","title",this.featureTitle);var description=this.getChildValue(item,"*","description",this.getChildValue(item,"*","content",this.getChildValue(item,"*","summary",this.featureDescription)));var link=this.getChildValue(item,"*","link");if(!link){try{link=this.getElementsByTagNameNS(item,"*","link")[0].getAttribute("href");}catch(e){link=null;}}
+var id=this.getChildValue(item,"*","id",null);var data={"title":title,"description":description,"link":link};var feature=new OpenLayers.Feature.Vector(geometry,data);feature.fid=id;return feature;},getChildValue:function(node,nsuri,name,def){var value;var eles=this.getElementsByTagNameNS(node,nsuri,name);if(eles&&eles[0]&&eles[0].firstChild&&eles[0].firstChild.nodeValue){value=eles[0].firstChild.nodeValue;}else{value=(def==undefined)?"":def;}
+return value;},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
+var itemlist=null;itemlist=this.getElementsByTagNameNS(doc,'*','item');if(itemlist.length==0){itemlist=this.getElementsByTagNameNS(doc,'*','entry');}
+var numItems=itemlist.length;var features=new Array(numItems);for(var i=0;i<numItems;i++){features[i]=this.createFeatureFromItem(itemlist[i]);}
+return features;},write:function(features){var georss;if(features instanceof Array){georss=this.createElementNS(this.rssns,"rss");for(var i=0,len=features.length;i<len;i++){georss.appendChild(this.createFeatureXML(features[i]));}}else{georss=this.createFeatureXML(features);}
+return OpenLayers.Format.XML.prototype.write.apply(this,[georss]);},createFeatureXML:function(feature){var geometryNode=this.buildGeometryNode(feature.geometry);var featureNode=this.createElementNS(this.rssns,"item");var titleNode=this.createElementNS(this.rssns,"title");titleNode.appendChild(this.createTextNode(feature.attributes.title?feature.attributes.title:""));var descNode=this.createElementNS(this.rssns,"description");descNode.appendChild(this.createTextNode(feature.attributes.description?feature.attributes.description:""));featureNode.appendChild(titleNode);featureNode.appendChild(descNode);if(feature.attributes.link){var linkNode=this.createElementNS(this.rssns,"link");linkNode.appendChild(this.createTextNode(feature.attributes.link));featureNode.appendChild(linkNode);}
+for(var attr in feature.attributes){if(attr=="link"||attr=="title"||attr=="description"){continue;}
+var attrText=this.createTextNode(feature.attributes[attr]);var nodename=attr;if(attr.search(":")!=-1){nodename=attr.split(":")[1];}
+var attrContainer=this.createElementNS(this.featureNS,"feature:"+nodename);attrContainer.appendChild(attrText);featureNode.appendChild(attrContainer);}
+featureNode.appendChild(geometryNode);return featureNode;},buildGeometryNode:function(geometry){if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
+var node;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Polygon"){node=this.createElementNS(this.georssns,'georss:polygon');node.appendChild(this.buildCoordinatesNode(geometry.components[0]));}
+else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LineString"){node=this.createElementNS(this.georssns,'georss:line');node.appendChild(this.buildCoordinatesNode(geometry));}
+else if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){node=this.createElementNS(this.georssns,'georss:point');node.appendChild(this.buildCoordinatesNode(geometry));}else{throw"Couldn't parse "+geometry.CLASS_NAME;}
+return node;},buildCoordinatesNode:function(geometry){var points=null;if(geometry.components){points=geometry.components;}
+var path;if(points){var numPoints=points.length;var parts=new Array(numPoints);for(var i=0;i<numPoints;i++){parts[i]=points[i].y+" "+points[i].x;}
+path=parts.join(" ");}else{path=geometry.y+" "+geometry.x;}
+return this.createTextNode(path);},CLASS_NAME:"OpenLayers.Format.GeoRSS"});OpenLayers.Format.KML=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{kml:"http://www.opengis.net/kml/2.2",gx:"http://www.google.com/kml/ext/2.2"},kmlns:"http://earth.google.com/kml/2.0",placemarksDesc:"No description available",foldersName:"OpenLayers export",foldersDesc:"Exported on "+new Date(),extractAttributes:true,extractStyles:false,extractTracks:false,trackAttributes:null,internalns:null,features:null,styles:null,styleBaseUrl:"",fetched:null,maxDepth:0,initialize:function(options){this.regExes={trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g),kmlColor:(/(\w{2})(\w{2})(\w{2})(\w{2})/),kmlIconPalette:(/root:\/\/icons\/palette-(\d+)(\.\w+)/),straightBracket:(/\$\[(.*?)\]/g)};this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){this.features=[];this.styles={};this.fetched={};var options={depth:0,styleBaseUrl:this.styleBaseUrl};return this.parseData(data,options);},parseData:function(data,options){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var types=["Link","NetworkLink","Style","StyleMap","Placemark"];for(var i=0,len=types.length;i<len;++i){var type=types[i];var nodes=this.getElementsByTagNameNS(data,"*",type);if(nodes.length==0){continue;}
+switch(type.toLowerCase()){case"link":case"networklink":this.parseLinks(nodes,options);break;case"style":if(this.extractStyles){this.parseStyles(nodes,options);}
+break;case"stylemap":if(this.extractStyles){this.parseStyleMaps(nodes,options);}
+break;case"placemark":this.parseFeatures(nodes,options);break;}}
+return this.features;},parseLinks:function(nodes,options){if(options.depth>=this.maxDepth){return false;}
+var newOptions=OpenLayers.Util.extend({},options);newOptions.depth++;for(var i=0,len=nodes.length;i<len;i++){var href=this.parseProperty(nodes[i],"*","href");if(href&&!this.fetched[href]){this.fetched[href]=true;var data=this.fetchLink(href);if(data){this.parseData(data,newOptions);}}}},fetchLink:function(href){var request=OpenLayers.Request.GET({url:href,async:false});if(request){return request.responseText;}},parseStyles:function(nodes,options){for(var i=0,len=nodes.length;i<len;i++){var style=this.parseStyle(nodes[i]);if(style){var styleName=(options.styleBaseUrl||"")+"#"+style.id;this.styles[styleName]=style;}}},parseKmlColor:function(kmlColor){var color=null;if(kmlColor){var matches=kmlColor.match(this.regExes.kmlColor);if(matches){color={color:'#'+matches[4]+matches[3]+matches[2],opacity:parseInt(matches[1],16)/255};}}
+return color;},parseStyle:function(node){var style={};var types=["LineStyle","PolyStyle","IconStyle","BalloonStyle","LabelStyle"];var type,nodeList,geometry,parser;for(var i=0,len=types.length;i<len;++i){type=types[i];styleTypeNode=this.getElementsByTagNameNS(node,"*",type)[0];if(!styleTypeNode){continue;}
+switch(type.toLowerCase()){case"linestyle":var kmlColor=this.parseProperty(styleTypeNode,"*","color");var color=this.parseKmlColor(kmlColor);if(color){style["strokeColor"]=color.color;style["strokeOpacity"]=color.opacity;}
+var width=this.parseProperty(styleTypeNode,"*","width");if(width){style["strokeWidth"]=width;}
+break;case"polystyle":var kmlColor=this.parseProperty(styleTypeNode,"*","color");var color=this.parseKmlColor(kmlColor);if(color){style["fillOpacity"]=color.opacity;style["fillColor"]=color.color;}
+var fill=this.parseProperty(styleTypeNode,"*","fill");if(fill=="0"){style["fillColor"]="none";}
+var outline=this.parseProperty(styleTypeNode,"*","outline");if(outline=="0"){style["strokeWidth"]="0";}
+break;case"iconstyle":var scale=parseFloat(this.parseProperty(styleTypeNode,"*","scale")||1);var width=32*scale;var height=32*scale;var iconNode=this.getElementsByTagNameNS(styleTypeNode,"*","Icon")[0];if(iconNode){var href=this.parseProperty(iconNode,"*","href");if(href){var w=this.parseProperty(iconNode,"*","w");var h=this.parseProperty(iconNode,"*","h");var google="http://maps.google.com/mapfiles/kml";if(OpenLayers.String.startsWith(href,google)&&!w&&!h){w=64;h=64;scale=scale/2;}
+w=w||h;h=h||w;if(w){width=parseInt(w)*scale;}
+if(h){height=parseInt(h)*scale;}
+var matches=href.match(this.regExes.kmlIconPalette);if(matches){var palette=matches[1];var file_extension=matches[2];var x=this.parseProperty(iconNode,"*","x");var y=this.parseProperty(iconNode,"*","y");var posX=x?x/32:0;var posY=y?(7-y/32):7;var pos=posY*8+posX;href="http://maps.google.com/mapfiles/kml/pal"
++palette+"/icon"+pos+file_extension;}
+style["graphicOpacity"]=1;style["externalGraphic"]=href;}}
+var hotSpotNode=this.getElementsByTagNameNS(styleTypeNode,"*","hotSpot")[0];if(hotSpotNode){var x=parseFloat(hotSpotNode.getAttribute("x"));var y=parseFloat(hotSpotNode.getAttribute("y"));var xUnits=hotSpotNode.getAttribute("xunits");if(xUnits=="pixels"){style["graphicXOffset"]=-x*scale;}
+else if(xUnits=="insetPixels"){style["graphicXOffset"]=-width+(x*scale);}
+else if(xUnits=="fraction"){style["graphicXOffset"]=-width*x;}
+var yUnits=hotSpotNode.getAttribute("yunits");if(yUnits=="pixels"){style["graphicYOffset"]=-height+(y*scale)+1;}
+else if(yUnits=="insetPixels"){style["graphicYOffset"]=-(y*scale)+1;}
+else if(yUnits=="fraction"){style["graphicYOffset"]=-height*(1-y)+1;}}
+style["graphicWidth"]=width;style["graphicHeight"]=height;break;case"balloonstyle":var balloonStyle=OpenLayers.Util.getXmlNodeValue(styleTypeNode);if(balloonStyle){style["balloonStyle"]=balloonStyle.replace(this.regExes.straightBracket,"${$1}");}
+break;case"labelstyle":var kmlColor=this.parseProperty(styleTypeNode,"*","color");var color=this.parseKmlColor(kmlColor);if(color){style["fontColor"]=color.color;style["fontOpacity"]=color.opacity;}
+break;default:}}
+if(!style["strokeColor"]&&style["fillColor"]){style["strokeColor"]=style["fillColor"];}
+var id=node.getAttribute("id");if(id&&style){style.id=id;}
+return style;},parseStyleMaps:function(nodes,options){for(var i=0,len=nodes.length;i<len;i++){var node=nodes[i];var pairs=this.getElementsByTagNameNS(node,"*","Pair");var id=node.getAttribute("id");for(var j=0,jlen=pairs.length;j<jlen;j++){var pair=pairs[j];var key=this.parseProperty(pair,"*","key");var styleUrl=this.parseProperty(pair,"*","styleUrl");if(styleUrl&&key=="normal"){this.styles[(options.styleBaseUrl||"")+"#"+id]=this.styles[(options.styleBaseUrl||"")+styleUrl];}
+if(styleUrl&&key=="highlight"){}}}},parseFeatures:function(nodes,options){var features=[];for(var i=0,len=nodes.length;i<len;i++){var featureNode=nodes[i];var feature=this.parseFeature.apply(this,[featureNode]);if(feature){if(this.extractStyles&&feature.attributes&&feature.attributes.styleUrl){feature.style=this.getStyle(feature.attributes.styleUrl,options);}
+if(this.extractStyles){var inlineStyleNode=this.getElementsByTagNameNS(featureNode,"*","Style")[0];if(inlineStyleNode){var inlineStyle=this.parseStyle(inlineStyleNode);if(inlineStyle){feature.style=OpenLayers.Util.extend(feature.style,inlineStyle);}}}
+if(this.extractTracks){var tracks=this.getElementsByTagNameNS(featureNode,this.namespaces.gx,"Track");if(tracks&&tracks.length>0){var track=tracks[0];var container={features:[],feature:feature};this.readNode(track,container);if(container.features.length>0){features.push.apply(features,container.features);}}}else{features.push(feature);}}else{throw"Bad Placemark: "+i;}}
+this.features=this.features.concat(features);},readers:{"kml":{"when":function(node,container){container.whens.push(OpenLayers.Date.parse(this.getChildValue(node)));},"_trackPointAttribute":function(node,container){var name=node.nodeName.split(":").pop();container.attributes[name].push(this.getChildValue(node));}},"gx":{"Track":function(node,container){var obj={whens:[],points:[],angles:[]};if(this.trackAttributes){var name;obj.attributes={};for(var i=0,ii=this.trackAttributes.length;i<ii;++i){name=this.trackAttributes[i];obj.attributes[name]=[];if(!(name in this.readers.kml)){this.readers.kml[name]=this.readers.kml._trackPointAttribute;}}}
+this.readChildNodes(node,obj);if(obj.whens.length!==obj.points.length){throw new Error("gx:Track with unequal number of when ("+obj.whens.length+") and gx:coord ("+obj.points.length+") elements.");}
+var hasAngles=obj.angles.length>0;if(hasAngles&&obj.whens.length!==obj.angles.length){throw new Error("gx:Track with unequal number of when ("+obj.whens.length+") and gx:angles ("+obj.angles.length+") elements.");}
+var feature,point,angles;for(var i=0,ii=obj.whens.length;i<ii;++i){feature=container.feature.clone();feature.fid=container.feature.fid||container.feature.id;point=obj.points[i];feature.geometry=point;if("z"in point){feature.attributes.altitude=point.z;}
+if(this.internalProjection&&this.externalProjection){feature.geometry.transform(this.externalProjection,this.internalProjection);}
+if(this.trackAttributes){for(var j=0,jj=this.trackAttributes.length;j<jj;++j){feature.attributes[name]=obj.attributes[this.trackAttributes[j]][i];}}
+feature.attributes.when=obj.whens[i];feature.attributes.trackId=container.feature.id;if(hasAngles){angles=obj.angles[i];feature.attributes.heading=parseFloat(angles[0]);feature.attributes.tilt=parseFloat(angles[1]);feature.attributes.roll=parseFloat(angles[2]);}
+container.features.push(feature);}},"coord":function(node,container){var str=this.getChildValue(node);var coords=str.replace(this.regExes.trimSpace,"").split(/\s+/);var point=new OpenLayers.Geometry.Point(coords[0],coords[1]);if(coords.length>2){point.z=parseFloat(coords[2]);}
+container.points.push(point);},"angles":function(node,container){var str=this.getChildValue(node);var parts=str.replace(this.regExes.trimSpace,"").split(/\s+/);container.angles.push(parts);}}},parseFeature:function(node){var order=["MultiGeometry","Polygon","LineString","Point"];var type,nodeList,geometry,parser;for(var i=0,len=order.length;i<len;++i){type=order[i];this.internalns=node.namespaceURI?node.namespaceURI:this.kmlns;nodeList=this.getElementsByTagNameNS(node,this.internalns,type);if(nodeList.length>0){var parser=this.parseGeometry[type.toLowerCase()];if(parser){geometry=parser.apply(this,[nodeList[0]]);if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}}else{OpenLayers.Console.error(OpenLayers.i18n("unsupportedGeometryType",{'geomType':type}));}
+break;}}
+var attributes;if(this.extractAttributes){attributes=this.parseAttributes(node);}
+var feature=new OpenLayers.Feature.Vector(geometry,attributes);var fid=node.getAttribute("id")||node.getAttribute("name");if(fid!=null){feature.fid=fid;}
+return feature;},getStyle:function(styleUrl,options){var styleBaseUrl=OpenLayers.Util.removeTail(styleUrl);var newOptions=OpenLayers.Util.extend({},options);newOptions.depth++;newOptions.styleBaseUrl=styleBaseUrl;if(!this.styles[styleUrl]&&!OpenLayers.String.startsWith(styleUrl,"#")&&newOptions.depth<=this.maxDepth&&!this.fetched[styleBaseUrl]){var data=this.fetchLink(styleBaseUrl);if(data){this.parseData(data,newOptions);}}
+var style=OpenLayers.Util.extend({},this.styles[styleUrl]);return style;},parseGeometry:{point:function(node){var nodeList=this.getElementsByTagNameNS(node,this.internalns,"coordinates");var coords=[];if(nodeList.length>0){var coordString=nodeList[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.removeSpace,"");coords=coordString.split(",");}
+var point=null;if(coords.length>1){if(coords.length==2){coords[2]=null;}
+point=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{throw"Bad coordinate string: "+coordString;}
+return point;},linestring:function(node,ring){var nodeList=this.getElementsByTagNameNS(node,this.internalns,"coordinates");var line=null;if(nodeList.length>0){var coordString=this.getChildValue(nodeList[0]);coordString=coordString.replace(this.regExes.trimSpace,"");coordString=coordString.replace(this.regExes.trimComma,",");var pointList=coordString.split(this.regExes.splitSpace);var numPoints=pointList.length;var points=new Array(numPoints);var coords,numCoords;for(var i=0;i<numPoints;++i){coords=pointList[i].split(",");numCoords=coords.length;if(numCoords>1){if(coords.length==2){coords[2]=null;}
+points[i]=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{throw"Bad LineString point coordinates: "+
+pointList[i];}}
+if(numPoints){if(ring){line=new OpenLayers.Geometry.LinearRing(points);}else{line=new OpenLayers.Geometry.LineString(points);}}else{throw"Bad LineString coordinates: "+coordString;}}
+return line;},polygon:function(node){var nodeList=this.getElementsByTagNameNS(node,this.internalns,"LinearRing");var numRings=nodeList.length;var components=new Array(numRings);if(numRings>0){var ring;for(var i=0,len=nodeList.length;i<len;++i){ring=this.parseGeometry.linestring.apply(this,[nodeList[i],true]);if(ring){components[i]=ring;}else{throw"Bad LinearRing geometry: "+i;}}}
+return new OpenLayers.Geometry.Polygon(components);},multigeometry:function(node){var child,parser;var parts=[];var children=node.childNodes;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){var type=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;var parser=this.parseGeometry[type.toLowerCase()];if(parser){parts.push(parser.apply(this,[child]));}}}
+return new OpenLayers.Geometry.Collection(parts);}},parseAttributes:function(node){var attributes={};var edNodes=node.getElementsByTagName("ExtendedData");if(edNodes.length){attributes=this.parseExtendedData(edNodes[0]);}
+var child,grandchildren,grandchild;var children=node.childNodes;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){grandchildren=child.childNodes;if(grandchildren.length>=1&&grandchildren.length<=3){var grandchild;switch(grandchildren.length){case 1:grandchild=grandchildren[0];break;case 2:var c1=grandchildren[0];var c2=grandchildren[1];grandchild=(c1.nodeType==3||c1.nodeType==4)?c1:c2;break;case 3:default:grandchild=grandchildren[1];break;}
+if(grandchild.nodeType==3||grandchild.nodeType==4){var name=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;var value=OpenLayers.Util.getXmlNodeValue(grandchild);if(value){value=value.replace(this.regExes.trimSpace,"");attributes[name]=value;}}}}}
+return attributes;},parseExtendedData:function(node){var attributes={};var i,len,data,key;var dataNodes=node.getElementsByTagName("Data");for(i=0,len=dataNodes.length;i<len;i++){data=dataNodes[i];key=data.getAttribute("name");var ed={};var valueNode=data.getElementsByTagName("value");if(valueNode.length){ed['value']=this.getChildValue(valueNode[0]);}
+var nameNode=data.getElementsByTagName("displayName");if(nameNode.length){ed['displayName']=this.getChildValue(nameNode[0]);}
+attributes[key]=ed;}
+var simpleDataNodes=node.getElementsByTagName("SimpleData");for(i=0,len=simpleDataNodes.length;i<len;i++){var ed={};data=simpleDataNodes[i];key=data.getAttribute("name");ed['value']=this.getChildValue(data);ed['displayName']=key;attributes[key]=ed;}
+return attributes;},parseProperty:function(xmlNode,namespace,tagName){var value;var nodeList=this.getElementsByTagNameNS(xmlNode,namespace,tagName);try{value=OpenLayers.Util.getXmlNodeValue(nodeList[0]);}catch(e){value=null;}
+return value;},write:function(features){if(!(features instanceof Array)){features=[features];}
+var kml=this.createElementNS(this.kmlns,"kml");var folder=this.createFolderXML();for(var i=0,len=features.length;i<len;++i){folder.appendChild(this.createPlacemarkXML(features[i]));}
+kml.appendChild(folder);return OpenLayers.Format.XML.prototype.write.apply(this,[kml]);},createFolderXML:function(){var folder=this.createElementNS(this.kmlns,"Folder");if(this.foldersName){var folderName=this.createElementNS(this.kmlns,"name");var folderNameText=this.createTextNode(this.foldersName);folderName.appendChild(folderNameText);folder.appendChild(folderName);}
+if(this.foldersDesc){var folderDesc=this.createElementNS(this.kmlns,"description");var folderDescText=this.createTextNode(this.foldersDesc);folderDesc.appendChild(folderDescText);folder.appendChild(folderDesc);}
+return folder;},createPlacemarkXML:function(feature){var placemarkName=this.createElementNS(this.kmlns,"name");var name=feature.style&&feature.style.label?feature.style.label:feature.attributes.name||feature.id;placemarkName.appendChild(this.createTextNode(name));var placemarkDesc=this.createElementNS(this.kmlns,"description");var desc=feature.attributes.description||this.placemarksDesc;placemarkDesc.appendChild(this.createTextNode(desc));var placemarkNode=this.createElementNS(this.kmlns,"Placemark");if(feature.fid!=null){placemarkNode.setAttribute("id",feature.fid);}
+placemarkNode.appendChild(placemarkName);placemarkNode.appendChild(placemarkDesc);var geometryNode=this.buildGeometryNode(feature.geometry);placemarkNode.appendChild(geometryNode);return placemarkNode;},buildGeometryNode:function(geometry){if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
+var className=geometry.CLASS_NAME;var type=className.substring(className.lastIndexOf(".")+1);var builder=this.buildGeometry[type.toLowerCase()];var node=null;if(builder){node=builder.apply(this,[geometry]);}
+return node;},buildGeometry:{point:function(geometry){var kml=this.createElementNS(this.kmlns,"Point");kml.appendChild(this.buildCoordinatesNode(geometry));return kml;},multipoint:function(geometry){return this.buildGeometry.collection.apply(this,[geometry]);},linestring:function(geometry){var kml=this.createElementNS(this.kmlns,"LineString");kml.appendChild(this.buildCoordinatesNode(geometry));return kml;},multilinestring:function(geometry){return this.buildGeometry.collection.apply(this,[geometry]);},linearring:function(geometry){var kml=this.createElementNS(this.kmlns,"LinearRing");kml.appendChild(this.buildCoordinatesNode(geometry));return kml;},polygon:function(geometry){var kml=this.createElementNS(this.kmlns,"Polygon");var rings=geometry.components;var ringMember,ringGeom,type;for(var i=0,len=rings.length;i<len;++i){type=(i==0)?"outerBoundaryIs":"innerBoundaryIs";ringMember=this.createElementNS(this.kmlns,type);ringGeom=this.buildGeometry.linearring.apply(this,[rings[i]]);ringMember.appendChild(ringGeom);kml.appendChild(ringMember);}
+return kml;},multipolygon:function(geometry){return this.buildGeometry.collection.apply(this,[geometry]);},collection:function(geometry){var kml=this.createElementNS(this.kmlns,"MultiGeometry");var child;for(var i=0,len=geometry.components.length;i<len;++i){child=this.buildGeometryNode.apply(this,[geometry.components[i]]);if(child){kml.appendChild(child);}}
+return kml;}},buildCoordinatesNode:function(geometry){var coordinatesNode=this.createElementNS(this.kmlns,"coordinates");var path;var points=geometry.components;if(points){var point;var numPoints=points.length;var parts=new Array(numPoints);for(var i=0;i<numPoints;++i){point=points[i];parts[i]=point.x+","+point.y;}
+path=parts.join(" ");}else{path=geometry.x+","+geometry.y;}
+var txtNode=this.createTextNode(path);coordinatesNode.appendChild(txtNode);return coordinatesNode;},CLASS_NAME:"OpenLayers.Format.KML"});OpenLayers.Format.OSM=OpenLayers.Class(OpenLayers.Format.XML,{checkTags:false,interestingTagsExclude:null,areaTags:null,initialize:function(options){var layer_defaults={'interestingTagsExclude':['source','source_ref','source:ref','history','attribution','created_by'],'areaTags':['area','building','leisure','tourism','ruins','historic','landuse','military','natural','sport']};layer_defaults=OpenLayers.Util.extend(layer_defaults,options);var interesting={};for(var i=0;i<layer_defaults.interestingTagsExclude.length;i++){interesting[layer_defaults.interestingTagsExclude[i]]=true;}
+layer_defaults.interestingTagsExclude=interesting;var area={};for(var i=0;i<layer_defaults.areaTags.length;i++){area[layer_defaults.areaTags[i]]=true;}
+layer_defaults.areaTags=area;this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this,[layer_defaults]);},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
+var nodes=this.getNodes(doc);var ways=this.getWays(doc);var feat_list=new Array(ways.length);for(var i=0;i<ways.length;i++){var point_list=new Array(ways[i].nodes.length);var poly=this.isWayArea(ways[i])?1:0;for(var j=0;j<ways[i].nodes.length;j++){var node=nodes[ways[i].nodes[j]];var point=new OpenLayers.Geometry.Point(node.lon,node.lat);point.osm_id=parseInt(ways[i].nodes[j]);point_list[j]=point;node.used=true;}
+var geometry=null;if(poly){geometry=new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(point_list));}else{geometry=new OpenLayers.Geometry.LineString(point_list);}
+if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}
+var feat=new OpenLayers.Feature.Vector(geometry,ways[i].tags);feat.osm_id=parseInt(ways[i].id);feat.fid="way."+feat.osm_id;feat_list[i]=feat;}
+for(var node_id in nodes){var node=nodes[node_id];if(!node.used||this.checkTags){var tags=null;if(this.checkTags){var result=this.getTags(node.node,true);if(node.used&&!result[1]){continue;}
+tags=result[0];}else{tags=this.getTags(node.node);}
+var feat=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(node['lon'],node['lat']),tags);if(this.internalProjection&&this.externalProjection){feat.geometry.transform(this.externalProjection,this.internalProjection);}
+feat.osm_id=parseInt(node_id);feat.fid="node."+feat.osm_id;feat_list.push(feat);}
+node.node=null;}
+return feat_list;},getNodes:function(doc){var node_list=doc.getElementsByTagName("node");var nodes={};for(var i=0;i<node_list.length;i++){var node=node_list[i];var id=node.getAttribute("id");nodes[id]={'lat':node.getAttribute("lat"),'lon':node.getAttribute("lon"),'node':node};}
+return nodes;},getWays:function(doc){var way_list=doc.getElementsByTagName("way");var return_ways=[];for(var i=0;i<way_list.length;i++){var way=way_list[i];var way_object={id:way.getAttribute("id")};way_object.tags=this.getTags(way);var node_list=way.getElementsByTagName("nd");way_object.nodes=new Array(node_list.length);for(var j=0;j<node_list.length;j++){way_object.nodes[j]=node_list[j].getAttribute("ref");}
+return_ways.push(way_object);}
+return return_ways;},getTags:function(dom_node,interesting_tags){var tag_list=dom_node.getElementsByTagName("tag");var tags={};var interesting=false;for(var j=0;j<tag_list.length;j++){var key=tag_list[j].getAttribute("k");tags[key]=tag_list[j].getAttribute("v");if(interesting_tags){if(!this.interestingTagsExclude[key]){interesting=true;}}}
+return interesting_tags?[tags,interesting]:tags;},isWayArea:function(way){var poly_shaped=false;var poly_tags=false;if(way.nodes[0]==way.nodes[way.nodes.length-1]){poly_shaped=true;}
+if(this.checkTags){for(var key in way.tags){if(this.areaTags[key]){poly_tags=true;break;}}}
+return poly_shaped&&(this.checkTags?poly_tags:true);},write:function(features){if(!(features instanceof Array)){features=[features];}
+this.osm_id=1;this.created_nodes={};var root_node=this.createElementNS(null,"osm");root_node.setAttribute("version","0.5");root_node.setAttribute("generator","OpenLayers "+OpenLayers.VERSION_NUMBER);for(var i=features.length-1;i>=0;i--){var nodes=this.createFeatureNodes(features[i]);for(var j=0;j<nodes.length;j++){root_node.appendChild(nodes[j]);}}
+return OpenLayers.Format.XML.prototype.write.apply(this,[root_node]);},createFeatureNodes:function(feature){var nodes=[];var className=feature.geometry.CLASS_NAME;var type=className.substring(className.lastIndexOf(".")+1);type=type.toLowerCase();var builder=this.createXML[type];if(builder){nodes=builder.apply(this,[feature]);}
+return nodes;},createXML:{'point':function(point){var id=null;var geometry=point.geometry?point.geometry:point;var already_exists=false;if(point.osm_id){id=point.osm_id;if(this.created_nodes[id]){already_exists=true;}}else{id=-this.osm_id;this.osm_id++;}
+if(already_exists){node=this.created_nodes[id];}else{var node=this.createElementNS(null,"node");}
+this.created_nodes[id]=node;node.setAttribute("id",id);node.setAttribute("lon",geometry.x);node.setAttribute("lat",geometry.y);if(point.attributes){this.serializeTags(point,node);}
+this.setState(point,node);return already_exists?[]:[node];},linestring:function(feature){var nodes=[];var geometry=feature.geometry;if(feature.osm_id){id=feature.osm_id;}else{id=-this.osm_id;this.osm_id++;}
+var way=this.createElementNS(null,"way");way.setAttribute("id",id);for(var i=0;i<geometry.components.length;i++){var node=this.createXML['point'].apply(this,[geometry.components[i]]);if(node.length){node=node[0];var node_ref=node.getAttribute("id");nodes.push(node);}else{node_ref=geometry.components[i].osm_id;node=this.created_nodes[node_ref];}
+this.setState(feature,node);var nd_dom=this.createElementNS(null,"nd");nd_dom.setAttribute("ref",node_ref);way.appendChild(nd_dom);}
+this.serializeTags(feature,way);nodes.push(way);return nodes;},polygon:function(feature){var attrs=OpenLayers.Util.extend({'area':'yes'},feature.attributes);var feat=new OpenLayers.Feature.Vector(feature.geometry.components[0],attrs);feat.osm_id=feature.osm_id;return this.createXML['linestring'].apply(this,[feat]);}},serializeTags:function(feature,node){for(var key in feature.attributes){var tag=this.createElementNS(null,"tag");tag.setAttribute("k",key);tag.setAttribute("v",feature.attributes[key]);node.appendChild(tag);}},setState:function(feature,node){if(feature.state){var state=null;switch(feature.state){case OpenLayers.State.UPDATE:state="modify";case OpenLayers.State.DELETE:state="delete";}
+if(state){node.setAttribute("action",state);}}},CLASS_NAME:"OpenLayers.Format.OSM"});OpenLayers.Geometry.MultiPolygon=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.Polygon"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Geometry.MultiPolygon"});OpenLayers.Handler.Polygon=OpenLayers.Class(OpenLayers.Handler.Path,{polygon:null,initialize:function(control,callbacks,options){OpenLayers.Handler.Path.prototype.initialize.apply(this,arguments);},createFeature:function(pixel){var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.line=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LinearRing([this.point.geometry]));this.polygon=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon([this.line.geometry]));this.callback("create",[this.point.geometry,this.getSketch()]);this.point.geometry.clearBounds();this.layer.addFeatures([this.polygon,this.point],{silent:true});},destroyFeature:function(){OpenLayers.Handler.Path.prototype.destroyFeature.apply(this);this.polygon=null;},drawFeature:function(){this.layer.drawFeature(this.polygon,this.style);this.layer.drawFeature(this.point,this.style);},getSketch:function(){return this.polygon;},getGeometry:function(){var geometry=this.polygon&&this.polygon.geometry;if(geometry&&this.multi){geometry=new OpenLayers.Geometry.MultiPolygon([geometry]);}
+return geometry;},dblclick:function(evt){if(!this.freehandMode(evt)){var index=this.line.geometry.components.length-2;this.line.geometry.removeComponent(this.line.geometry.components[index]);this.removePoint();this.finalize();}
+return false;},CLASS_NAME:"OpenLayers.Handler.Polygon"});OpenLayers.Control.EditingToolbar=OpenLayers.Class(OpenLayers.Control.Panel,{initialize:function(layer,options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.Navigation()]);var controls=[new OpenLayers.Control.DrawFeature(layer,OpenLayers.Handler.Point,{'displayClass':'olControlDrawFeaturePoint'}),new OpenLayers.Control.DrawFeature(layer,OpenLayers.Handler.Path,{'displayClass':'olControlDrawFeaturePath'}),new OpenLayers.Control.DrawFeature(layer,OpenLayers.Handler.Polygon,{'displayClass':'olControlDrawFeaturePolygon'})];this.addControls(controls);},draw:function(){var div=OpenLayers.Control.Panel.prototype.draw.apply(this,arguments);this.activateControl(this.controls[0]);return div;},CLASS_NAME:"OpenLayers.Control.EditingToolbar"});OpenLayers.Control.SLDSelect=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["selected"],clearOnDeactivate:false,layers:null,callbacks:null,selectionSymbolizer:{'Polygon':{fillColor:'#FF0000',stroke:false},'Line':{strokeColor:'#FF0000',strokeWidth:2},'Point':{graphicName:'square',fillColor:'#FF0000',pointRadius:5}},layerOptions:null,handlerOptions:null,sketchStyle:null,wfsCache:{},layerCache:{},initialize:function(handler,options){this.EVENT_TYPES=OpenLayers.Control.SLDSelect.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.callbacks=OpenLayers.Util.extend({done:this.select,click:this.select},this.callbacks);this.handlerOptions=this.handlerOptions||{};this.layerOptions=OpenLayers.Util.applyDefaults(this.layerOptions,{displayInLayerSwitcher:false});if(this.sketchStyle){this.handlerOptions.layerOptions=OpenLayers.Util.applyDefaults(this.handlerOptions.layerOptions,{styleMap:new OpenLayers.StyleMap({"default":this.sketchStyle})});}
+this.handler=new handler(this,this.callbacks,this.handlerOptions);},destroy:function(){for(var key in this.layerCache){delete this.layerCache[key];}
+for(var key in this.wfsCache){delete this.wfsCache[key];}
+OpenLayers.Control.prototype.destroy.apply(this,arguments);},coupleLayerVisiblity:function(evt){this.setVisibility(evt.object.getVisibility());},createSelectionLayer:function(source){var selectionLayer;if(!this.layerCache[source.id]){selectionLayer=new OpenLayers.Layer.WMS.Post(source.name,source.url,source.params,OpenLayers.Util.applyDefaults(this.layerOptions,source.getOptions()));this.layerCache[source.id]=selectionLayer;if(this.layerOptions.displayInLayerSwitcher===false){source.events.on({"visibilitychanged":this.coupleLayerVisiblity,scope:selectionLayer});}
+this.map.addLayer(selectionLayer);}else{selectionLayer=this.layerCache[source.id];}
+return selectionLayer;},createSLD:function(layer,filters,geometryAttributes){var sld={version:"1.0.0",namedLayers:{}};var layerNames=[layer.params.LAYERS].join(",").split(",");for(var i=0,len=layerNames.length;i<len;i++){var name=layerNames[i];sld.namedLayers[name]={name:name,userStyles:[]};var symbolizer=this.selectionSymbolizer;var geometryAttribute=geometryAttributes[i];if(geometryAttribute.type.indexOf('Polygon')>=0){symbolizer={Polygon:this.selectionSymbolizer['Polygon']};}else if(geometryAttribute.type.indexOf('LineString')>=0){symbolizer={Line:this.selectionSymbolizer['Line']};}else if(geometryAttribute.type.indexOf('Point')>=0){symbolizer={Point:this.selectionSymbolizer['Point']};}
+var filter=filters[i];sld.namedLayers[name].userStyles.push({name:'default',rules:[new OpenLayers.Rule({symbolizer:symbolizer,filter:filter,maxScaleDenominator:layer.options.minScale})]});}
+return new OpenLayers.Format.SLD().write(sld);},parseDescribeLayer:function(request){var format=new OpenLayers.Format.WMSDescribeLayer();var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
+var describeLayer=format.read(doc);var typeNames=[];var url=null;for(var i=0,len=describeLayer.length;i<len;i++){if(describeLayer[i].owsType=="WFS"){typeNames.push(describeLayer[i].typeName);url=describeLayer[i].owsURL;}}
+var options={url:url,params:{SERVICE:"WFS",TYPENAME:typeNames.toString(),REQUEST:"DescribeFeatureType",VERSION:"1.0.0"},callback:function(request){var format=new OpenLayers.Format.WFSDescribeFeatureType();var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
+var describeFeatureType=format.read(doc);this.control.wfsCache[this.layer.id]=describeFeatureType;this.control._queue&&this.control.applySelection();},scope:this};OpenLayers.Request.GET(options);},getGeometryAttributes:function(layer){var result=[];var cache=this.wfsCache[layer.id];for(var i=0,len=cache.featureTypes.length;i<len;i++){var typeName=cache.featureTypes[i];var properties=typeName.properties;for(var j=0,lenj=properties.length;j<lenj;j++){var property=properties[j];var type=property.type;if((type.indexOf('LineString')>=0)||(type.indexOf('GeometryAssociationType')>=0)||(type.indexOf('GeometryPropertyType')>=0)||(type.indexOf('Point')>=0)||(type.indexOf('Polygon')>=0)){result.push(property);}}}
+return result;},activate:function(){var activated=OpenLayers.Control.prototype.activate.call(this);if(activated){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer&&!this.wfsCache[layer.id]){var options={url:layer.url,params:{SERVICE:"WMS",VERSION:layer.params.VERSION,LAYERS:layer.params.LAYERS,REQUEST:"DescribeLayer"},callback:this.parseDescribeLayer,scope:{layer:layer,control:this}};OpenLayers.Request.GET(options);}}}
+return activated;},deactivate:function(){var deactivated=OpenLayers.Control.prototype.deactivate.call(this);if(deactivated){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer&&this.clearOnDeactivate===true){var layerCache=this.layerCache;var selectionLayer=layerCache[layer.id];if(selectionLayer){layer.events.un({"visibilitychanged":this.coupleLayerVisiblity,scope:selectionLayer});selectionLayer.destroy();delete layerCache[layer.id];}}}}
+return deactivated;},setLayers:function(layers){if(this.active){this.deactivate();this.layers=layers;this.activate();}else{this.layers=layers;}},createFilter:function(geometryAttribute,geometry){var filter=null;if(this.handler instanceof OpenLayers.Handler.RegularPolygon){if(this.handler.irregular===true){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.BBOX,property:geometryAttribute.name,value:geometry.getBounds()});}else{filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}}else if(this.handler instanceof OpenLayers.Handler.Polygon){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}else if(this.handler instanceof OpenLayers.Handler.Path){if(geometryAttribute.type.indexOf('Point')>=0){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.DWITHIN,property:geometryAttribute.name,distance:this.map.getExtent().getWidth()*0.01,distanceUnits:this.map.getUnits(),value:geometry});}else{filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}}else if(this.handler instanceof OpenLayers.Handler.Click){if(geometryAttribute.type.indexOf('Polygon')>=0){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}else{filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.DWITHIN,property:geometryAttribute.name,distance:this.map.getExtent().getWidth()*0.01,distanceUnits:this.map.getUnits(),value:geometry});}}
+return filter;},select:function(geometry){this._queue=function(){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];var geometryAttributes=this.getGeometryAttributes(layer);var filters=[];for(var j=0,lenj=geometryAttributes.length;j<lenj;j++){var geometryAttribute=geometryAttributes[j];if(geometryAttribute!==null){if(!(geometry instanceof OpenLayers.Geometry)){var point=this.map.getLonLatFromPixel(geometry.xy);geometry=new OpenLayers.Geometry.Point(point.lon,point.lat);}
+var filter=this.createFilter(geometryAttribute,geometry);if(filter!==null){filters.push(filter);}}}
+var selectionLayer=this.createSelectionLayer(layer);var sld=this.createSLD(layer,filters,geometryAttributes);this.events.triggerEvent("selected",{layer:layer,filters:filters});selectionLayer.mergeNewParams({SLD_BODY:sld});delete this._queue;}};this.applySelection();},applySelection:function(){var canApply=true;for(var i=0,len=this.layers.length;i<len;i++){if(!this.wfsCache[this.layers[i].id]){canApply=false;break;}}
+canApply&&this._queue.call(this);},CLASS_NAME:"OpenLayers.Control.SLDSelect"});OpenLayers.Format.ArcXML=OpenLayers.Class(OpenLayers.Format.XML,{fontStyleKeys:['antialiasing','blockout','font','fontcolor','fontsize','fontstyle','glowing','interval','outline','printmode','shadow','transparency'],request:null,response:null,initialize:function(options){this.request=new OpenLayers.Format.ArcXML.Request();this.response=new OpenLayers.Format.ArcXML.Response();if(options){if(options.requesttype=="feature"){this.request.get_image=null;var qry=this.request.get_feature.query;this.addCoordSys(qry.featurecoordsys,options.featureCoordSys);this.addCoordSys(qry.filtercoordsys,options.filterCoordSys);if(options.polygon){qry.isspatial=true;qry.spatialfilter.polygon=options.polygon;}else if(options.envelope){qry.isspatial=true;qry.spatialfilter.envelope={minx:0,miny:0,maxx:0,maxy:0};this.parseEnvelope(qry.spatialfilter.envelope,options.envelope);}}else if(options.requesttype=="image"){this.request.get_feature=null;var props=this.request.get_image.properties;this.parseEnvelope(props.envelope,options.envelope);this.addLayers(props.layerlist,options.layers);this.addImageSize(props.imagesize,options.tileSize);this.addCoordSys(props.featurecoordsys,options.featureCoordSys);this.addCoordSys(props.filtercoordsys,options.filterCoordSys);}else{this.request=null;}}
+OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},parseEnvelope:function(env,arr){if(arr&&arr.length==4){env.minx=arr[0];env.miny=arr[1];env.maxx=arr[2];env.maxy=arr[3];}},addLayers:function(ll,lyrs){for(var lind=0,len=lyrs.length;lind<len;lind++){ll.push(lyrs[lind]);}},addImageSize:function(imsize,olsize){if(olsize!==null){imsize.width=olsize.w;imsize.height=olsize.h;imsize.printwidth=olsize.w;imsize.printheight=olsize.h;}},addCoordSys:function(featOrFilt,fsys){if(typeof fsys=="string"){featOrFilt.id=parseInt(fsys);featOrFilt.string=fsys;}
+else if(typeof fsys=="object"&&fsys.proj!==null){featOrFilt.id=fsys.proj.srsProjNumber;featOrFilt.string=fsys.proj.srsCode;}else{featOrFilt=fsys;}},iserror:function(data){var ret=null;if(!data){ret=(this.response.error!=='');}else{data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);var errorNodes=data.documentElement.getElementsByTagName("ERROR");ret=(errorNodes!==null&&errorNodes.length>0);}
+return ret;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var arcNode=null;if(data&&data.documentElement){if(data.documentElement.nodeName=="ARCXML"){arcNode=data.documentElement;}else{arcNode=data.documentElement.getElementsByTagName("ARCXML")[0];}}
+if(!arcNode||arcNode.firstChild.nodeName==='parsererror'){var error,source;try{error=data.firstChild.nodeValue;source=data.firstChild.childNodes[1].firstChild.nodeValue;}catch(err){}
+throw{message:"Error parsing the ArcXML request",error:error,source:source};}
+var response=this.parseResponse(arcNode);return response;},write:function(request){if(!request){request=this.request;}
+var root=this.createElementNS("","ARCXML");root.setAttribute("version","1.1");var reqElem=this.createElementNS("","REQUEST");if(request.get_image!=null){var getElem=this.createElementNS("","GET_IMAGE");reqElem.appendChild(getElem);var propElem=this.createElementNS("","PROPERTIES");getElem.appendChild(propElem);var props=request.get_image.properties;if(props.featurecoordsys!=null){var feat=this.createElementNS("","FEATURECOORDSYS");propElem.appendChild(feat);if(props.featurecoordsys.id===0){feat.setAttribute("string",props.featurecoordsys['string']);}
+else{feat.setAttribute("id",props.featurecoordsys.id);}}
+if(props.filtercoordsys!=null){var filt=this.createElementNS("","FILTERCOORDSYS");propElem.appendChild(filt);if(props.filtercoordsys.id===0){filt.setAttribute("string",props.filtercoordsys.string);}
+else{filt.setAttribute("id",props.filtercoordsys.id);}}
+if(props.envelope!=null){var env=this.createElementNS("","ENVELOPE");propElem.appendChild(env);env.setAttribute("minx",props.envelope.minx);env.setAttribute("miny",props.envelope.miny);env.setAttribute("maxx",props.envelope.maxx);env.setAttribute("maxy",props.envelope.maxy);}
+var imagesz=this.createElementNS("","IMAGESIZE");propElem.appendChild(imagesz);imagesz.setAttribute("height",props.imagesize.height);imagesz.setAttribute("width",props.imagesize.width);if(props.imagesize.height!=props.imagesize.printheight||props.imagesize.width!=props.imagesize.printwidth){imagesz.setAttribute("printheight",props.imagesize.printheight);imagesz.setArrtibute("printwidth",props.imagesize.printwidth);}
+if(props.background!=null){var backgrnd=this.createElementNS("","BACKGROUND");propElem.appendChild(backgrnd);backgrnd.setAttribute("color",props.background.color.r+","+
+props.background.color.g+","+
+props.background.color.b);if(props.background.transcolor!==null){backgrnd.setAttribute("transcolor",props.background.transcolor.r+","+
+props.background.transcolor.g+","+
+props.background.transcolor.b);}}
+if(props.layerlist!=null&&props.layerlist.length>0){var layerlst=this.createElementNS("","LAYERLIST");propElem.appendChild(layerlst);for(var ld=0;ld<props.layerlist.length;ld++){var ldef=this.createElementNS("","LAYERDEF");layerlst.appendChild(ldef);ldef.setAttribute("id",props.layerlist[ld].id);ldef.setAttribute("visible",props.layerlist[ld].visible);if(typeof props.layerlist[ld].query=="object"){var query=props.layerlist[ld].query;if(query.where.length<0){continue;}
+var queryElem=null;if(typeof query.spatialfilter=="boolean"&&query.spatialfilter){queryElem=this.createElementNS("","SPATIALQUERY");}
+else{queryElem=this.createElementNS("","QUERY");}
+queryElem.setAttribute("where",query.where);if(typeof query.accuracy=="number"&&query.accuracy>0){queryElem.setAttribute("accuracy",query.accuracy);}
+if(typeof query.featurelimit=="number"&&query.featurelimit<2000){queryElem.setAttribute("featurelimit",query.featurelimit);}
+if(typeof query.subfields=="string"&&query.subfields!="#ALL#"){queryElem.setAttribute("subfields",query.subfields);}
+if(typeof query.joinexpression=="string"&&query.joinexpression.length>0){queryElem.setAttribute("joinexpression",query.joinexpression);}
+if(typeof query.jointables=="string"&&query.jointables.length>0){queryElem.setAttribute("jointables",query.jointables);}
+ldef.appendChild(queryElem);}
+if(typeof props.layerlist[ld].renderer=="object"){this.addRenderer(ldef,props.layerlist[ld].renderer);}}}}else if(request.get_feature!=null){var getElem=this.createElementNS("","GET_FEATURES");getElem.setAttribute("outputmode","newxml");getElem.setAttribute("checkesc","true");if(request.get_feature.geometry){getElem.setAttribute("geometry",request.get_feature.geometry);}
+else{getElem.setAttribute("geometry","false");}
+if(request.get_feature.compact){getElem.setAttribute("compact",request.get_feature.compact);}
+if(request.get_feature.featurelimit=="number"){getElem.setAttribute("featurelimit",request.get_feature.featurelimit);}
+getElem.setAttribute("globalenvelope","true");reqElem.appendChild(getElem);if(request.get_feature.layer!=null&&request.get_feature.layer.length>0){var lyrElem=this.createElementNS("","LAYER");lyrElem.setAttribute("id",request.get_feature.layer);getElem.appendChild(lyrElem);}
+var fquery=request.get_feature.query;if(fquery!=null){var qElem=null;if(fquery.isspatial){qElem=this.createElementNS("","SPATIALQUERY");}else{qElem=this.createElementNS("","QUERY");}
+getElem.appendChild(qElem);if(typeof fquery.accuracy=="number"){qElem.setAttribute("accuracy",fquery.accuracy);}
+if(fquery.featurecoordsys!=null){var fcsElem1=this.createElementNS("","FEATURECOORDSYS");if(fquery.featurecoordsys.id==0){fcsElem1.setAttribute("string",fquery.featurecoordsys.string);}else{fcsElem1.setAttribute("id",fquery.featurecoordsys.id);}
+qElem.appendChild(fcsElem1);}
+if(fquery.filtercoordsys!=null){var fcsElem2=this.createElementNS("","FILTERCOORDSYS");if(fquery.filtercoordsys.id===0){fcsElem2.setAttribute("string",fquery.filtercoordsys.string);}else{fcsElem2.setAttribute("id",fquery.filtercoordsys.id);}
+qElem.appendChild(fcsElem2);}
+if(fquery.buffer>0){var bufElem=this.createElementNS("","BUFFER");bufElem.setAttribute("distance",fquery.buffer);qElem.appendChild(bufElem);}
+if(fquery.isspatial){var spfElem=this.createElementNS("","SPATIALFILTER");spfElem.setAttribute("relation",fquery.spatialfilter.relation);qElem.appendChild(spfElem);if(fquery.spatialfilter.envelope){var envElem=this.createElementNS("","ENVELOPE");envElem.setAttribute("minx",fquery.spatialfilter.envelope.minx);envElem.setAttribute("miny",fquery.spatialfilter.envelope.miny);envElem.setAttribute("maxx",fquery.spatialfilter.envelope.maxx);envElem.setAttribute("maxy",fquery.spatialfilter.envelope.maxy);spfElem.appendChild(envElem);}else if(typeof fquery.spatialfilter.polygon=="object"){spfElem.appendChild(this.writePolygonGeometry(fquery.spatialfilter.polygon));}}
+if(fquery.where!=null&&fquery.where.length>0){qElem.setAttribute("where",fquery.where);}}}
+root.appendChild(reqElem);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},addGroupRenderer:function(ldef,toprenderer){var topRelem=this.createElementNS("","GROUPRENDERER");ldef.appendChild(topRelem);for(var rind=0;rind<toprenderer.length;rind++){var renderer=toprenderer[rind];this.addRenderer(topRelem,renderer);}},addRenderer:function(topRelem,renderer){if(renderer instanceof Array){this.addGroupRenderer(topRelem,renderer);}else{var renderElem=this.createElementNS("",renderer.type.toUpperCase()+"RENDERER");topRelem.appendChild(renderElem);if(renderElem.tagName=="VALUEMAPRENDERER"){this.addValueMapRenderer(renderElem,renderer);}else if(renderElem.tagName=="VALUEMAPLABELRENDERER"){this.addValueMapLabelRenderer(renderElem,renderer);}else if(renderElem.tagName=="SIMPLELABELRENDERER"){this.addSimpleLabelRenderer(renderElem,renderer);}else if(renderElem.tagName=="SCALEDEPENDENTRENDERER"){this.addScaleDependentRenderer(renderElem,renderer);}}},addScaleDependentRenderer:function(renderElem,renderer){if(typeof renderer.lower=="string"||typeof renderer.lower=="number"){renderElem.setAttribute("lower",renderer.lower);}
+if(typeof renderer.upper=="string"||typeof renderer.upper=="number"){renderElem.setAttribute("upper",renderer.upper);}
+this.addRenderer(renderElem,renderer.renderer);},addValueMapLabelRenderer:function(renderElem,renderer){renderElem.setAttribute("lookupfield",renderer.lookupfield);renderElem.setAttribute("labelfield",renderer.labelfield);if(typeof renderer.exacts=="object"){for(var ext=0,extlen=renderer.exacts.length;ext<extlen;ext++){var exact=renderer.exacts[ext];var eelem=this.createElementNS("","EXACT");if(typeof exact.value=="string"){eelem.setAttribute("value",exact.value);}
+if(typeof exact.label=="string"){eelem.setAttribute("label",exact.label);}
+if(typeof exact.method=="string"){eelem.setAttribute("method",exact.method);}
+renderElem.appendChild(eelem);if(typeof exact.symbol=="object"){var selem=null;if(exact.symbol.type=="text"){selem=this.createElementNS("","TEXTSYMBOL");}
+if(selem!=null){var keys=this.fontStyleKeys;for(var i=0,len=keys.length;i<len;i++){var key=keys[i];if(exact.symbol[key]){selem.setAttribute(key,exact.symbol[key]);}}
+eelem.appendChild(selem);}}}}},addValueMapRenderer:function(renderElem,renderer){renderElem.setAttribute("lookupfield",renderer.lookupfield);if(typeof renderer.ranges=="object"){for(var rng=0,rnglen=renderer.ranges.length;rng<rnglen;rng++){var range=renderer.ranges[rng];var relem=this.createElementNS("","RANGE");relem.setAttribute("lower",range.lower);relem.setAttribute("upper",range.upper);renderElem.appendChild(relem);if(typeof range.symbol=="object"){var selem=null;if(range.symbol.type=="simplepolygon"){selem=this.createElementNS("","SIMPLEPOLYGONSYMBOL");}
+if(selem!=null){if(typeof range.symbol.boundarycolor=="string"){selem.setAttribute("boundarycolor",range.symbol.boundarycolor);}
+if(typeof range.symbol.fillcolor=="string"){selem.setAttribute("fillcolor",range.symbol.fillcolor);}
+if(typeof range.symbol.filltransparency=="number"){selem.setAttribute("filltransparency",range.symbol.filltransparency);}
+relem.appendChild(selem);}}}}else if(typeof renderer.exacts=="object"){for(var ext=0,extlen=renderer.exacts.length;ext<extlen;ext++){var exact=renderer.exacts[ext];var eelem=this.createElementNS("","EXACT");if(typeof exact.value=="string"){eelem.setAttribute("value",exact.value);}
+if(typeof exact.label=="string"){eelem.setAttribute("label",exact.label);}
+if(typeof exact.method=="string"){eelem.setAttribute("method",exact.method);}
+renderElem.appendChild(eelem);if(typeof exact.symbol=="object"){var selem=null;if(exact.symbol.type=="simplemarker"){selem=this.createElementNS("","SIMPLEMARKERSYMBOL");}
+if(selem!=null){if(typeof exact.symbol.antialiasing=="string"){selem.setAttribute("antialiasing",exact.symbol.antialiasing);}
+if(typeof exact.symbol.color=="string"){selem.setAttribute("color",exact.symbol.color);}
+if(typeof exact.symbol.outline=="string"){selem.setAttribute("outline",exact.symbol.outline);}
+if(typeof exact.symbol.overlap=="string"){selem.setAttribute("overlap",exact.symbol.overlap);}
+if(typeof exact.symbol.shadow=="string"){selem.setAttribute("shadow",exact.symbol.shadow);}
+if(typeof exact.symbol.transparency=="number"){selem.setAttribute("transparency",exact.symbol.transparency);}
+if(typeof exact.symbol.usecentroid=="string"){selem.setAttribute("usecentroid",exact.symbol.usecentroid);}
+if(typeof exact.symbol.width=="number"){selem.setAttribute("width",exact.symbol.width);}
+eelem.appendChild(selem);}}}}},addSimpleLabelRenderer:function(renderElem,renderer){renderElem.setAttribute("field",renderer.field);var keys=['featureweight','howmanylabels','labelbufferratio','labelpriorities','labelweight','linelabelposition','rotationalangles'];for(var i=0,len=keys.length;i<len;i++){var key=keys[i];if(renderer[key]){renderElem.setAttribute(key,renderer[key]);}}
+if(renderer.symbol.type=="text"){var symbol=renderer.symbol;var selem=this.createElementNS("","TEXTSYMBOL");renderElem.appendChild(selem);var keys=this.fontStyleKeys;for(var i=0,len=keys.length;i<len;i++){var key=keys[i];if(symbol[key]){selem.setAttribute(key,renderer[key]);}}}},writePolygonGeometry:function(polygon){if(!(polygon instanceof OpenLayers.Geometry.Polygon)){throw{message:'Cannot write polygon geometry to ArcXML with an '+
+polygon.CLASS_NAME+' object.',geometry:polygon};}
+var polyElem=this.createElementNS("","POLYGON");for(var ln=0,lnlen=polygon.components.length;ln<lnlen;ln++){var ring=polygon.components[ln];var ringElem=this.createElementNS("","RING");for(var rn=0,rnlen=ring.components.length;rn<rnlen;rn++){var point=ring.components[rn];var pointElem=this.createElementNS("","POINT");pointElem.setAttribute("x",point.x);pointElem.setAttribute("y",point.y);ringElem.appendChild(pointElem);}
+polyElem.appendChild(ringElem);}
+return polyElem;},parseResponse:function(data){if(typeof data=="string"){var newData=new OpenLayers.Format.XML();data=newData.read(data);}
+var response=new OpenLayers.Format.ArcXML.Response();var errorNode=data.getElementsByTagName("ERROR");if(errorNode!=null&&errorNode.length>0){response.error=this.getChildValue(errorNode,"Unknown error.");}else{var responseNode=data.getElementsByTagName("RESPONSE");if(responseNode==null||responseNode.length==0){response.error="No RESPONSE tag found in ArcXML response.";return response;}
+var rtype=responseNode[0].firstChild.nodeName;if(rtype=="#text"){rtype=responseNode[0].firstChild.nextSibling.nodeName;}
+if(rtype=="IMAGE"){var envelopeNode=data.getElementsByTagName("ENVELOPE");var outputNode=data.getElementsByTagName("OUTPUT");if(envelopeNode==null||envelopeNode.length==0){response.error="No ENVELOPE tag found in ArcXML response.";}else if(outputNode==null||outputNode.length==0){response.error="No OUTPUT tag found in ArcXML response.";}else{var envAttr=this.parseAttributes(envelopeNode[0]);var outputAttr=this.parseAttributes(outputNode[0]);if(typeof outputAttr.type=="string"){response.image={envelope:envAttr,output:{type:outputAttr.type,data:this.getChildValue(outputNode[0])}};}else{response.image={envelope:envAttr,output:outputAttr};}}}else if(rtype=="FEATURES"){var features=responseNode[0].getElementsByTagName("FEATURES");var featureCount=features[0].getElementsByTagName("FEATURECOUNT");response.features.featurecount=featureCount[0].getAttribute("count");if(response.features.featurecount>0){var envelope=features[0].getElementsByTagName("ENVELOPE");response.features.envelope=this.parseAttributes(envelope[0],typeof(0));var featureList=features[0].getElementsByTagName("FEATURE");for(var fn=0;fn<featureList.length;fn++){var feature=new OpenLayers.Feature.Vector();var fields=featureList[fn].getElementsByTagName("FIELD");for(var fdn=0;fdn<fields.length;fdn++){var fieldName=fields[fdn].getAttribute("name");var fieldValue=fields[fdn].getAttribute("value");feature.attributes[fieldName]=fieldValue;}
+var geom=featureList[fn].getElementsByTagName("POLYGON");if(geom.length>0){var ring=geom[0].getElementsByTagName("RING");var polys=[];for(var rn=0;rn<ring.length;rn++){var linearRings=[];linearRings.push(this.parsePointGeometry(ring[rn]));var holes=ring[rn].getElementsByTagName("HOLE");for(var hn=0;hn<holes.length;hn++){linearRings.push(this.parsePointGeometry(holes[hn]));}
+holes=null;polys.push(new OpenLayers.Geometry.Polygon(linearRings));linearRings=null;}
+ring=null;if(polys.length==1){feature.geometry=polys[0];}else
+{feature.geometry=new OpenLayers.Geometry.MultiPolygon(polys);}}
+response.features.feature.push(feature);}}}else{response.error="Unidentified response type.";}}
+return response;},parseAttributes:function(node,type){var attributes={};for(var attr=0;attr<node.attributes.length;attr++){if(type=="number"){attributes[node.attributes[attr].nodeName]=parseFloat(node.attributes[attr].nodeValue);}else{attributes[node.attributes[attr].nodeName]=node.attributes[attr].nodeValue;}}
+return attributes;},parsePointGeometry:function(node){var ringPoints=[];var coords=node.getElementsByTagName("COORDS");if(coords.length>0){var coordArr=this.getChildValue(coords[0]);coordArr=coordArr.split(/;/);for(var cn=0;cn<coordArr.length;cn++){var coordItems=coordArr[cn].split(/ /);ringPoints.push(new OpenLayers.Geometry.Point(parseFloat(coordItems[0]),parseFloat(coordItems[1])));}
+coords=null;}else{var point=node.getElementsByTagName("POINT");if(point.length>0){for(var pn=0;pn<point.length;pn++){ringPoints.push(new OpenLayers.Geometry.Point(parseFloat(point[pn].getAttribute("x")),parseFloat(point[pn].getAttribute("y"))));}}
+point=null;}
+return new OpenLayers.Geometry.LinearRing(ringPoints);},CLASS_NAME:"OpenLayers.Format.ArcXML"});OpenLayers.Format.ArcXML.Request=OpenLayers.Class({initialize:function(params){var defaults={get_image:{properties:{background:null,draw:true,envelope:{minx:0,miny:0,maxx:0,maxy:0},featurecoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},filtercoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},imagesize:{height:0,width:0,dpi:96,printheight:0,printwidth:0,scalesymbols:false},layerlist:[],output:{baseurl:"",legendbaseurl:"",legendname:"",legendpath:"",legendurl:"",name:"",path:"",type:"jpg",url:""}}},get_feature:{layer:"",query:{isspatial:false,featurecoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},filtercoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},buffer:0,where:"",spatialfilter:{relation:"envelope_intersection",envelope:null}}},environment:{separators:{cs:" ",ts:";"}},layer:[],workspaces:[]};return OpenLayers.Util.extend(this,defaults);},CLASS_NAME:"OpenLayers.Format.ArcXML.Request"});OpenLayers.Format.ArcXML.Response=OpenLayers.Class({initialize:function(params){var defaults={image:{envelope:null,output:''},features:{featurecount:0,envelope:null,feature:[]},error:''};return OpenLayers.Util.extend(this,defaults);},CLASS_NAME:"OpenLayers.Format.ArcXML.Response"});OpenLayers.Format.GML=OpenLayers.Class(OpenLayers.Format.XML,{featureNS:"http://mapserver.gis.umn.edu/mapserver",featurePrefix:"feature",featureName:"featureMember",layerName:"features",geometryName:"geometry",collectionName:"FeatureCollection",gmlns:"http://www.opengis.net/gml",extractAttributes:true,xy:true,initialize:function(options){this.regExes={trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)};OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+var featureNodes=this.getElementsByTagNameNS(data.documentElement,this.gmlns,this.featureName);var features=[];for(var i=0;i<featureNodes.length;i++){var feature=this.parseFeature(featureNodes[i]);if(feature){features.push(feature);}}
+return features;},parseFeature:function(node){var order=["MultiPolygon","Polygon","MultiLineString","LineString","MultiPoint","Point","Envelope"];var type,nodeList,geometry,parser;for(var i=0;i<order.length;++i){type=order[i];nodeList=this.getElementsByTagNameNS(node,this.gmlns,type);if(nodeList.length>0){parser=this.parseGeometry[type.toLowerCase()];if(parser){geometry=parser.apply(this,[nodeList[0]]);if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}}else{OpenLayers.Console.error(OpenLayers.i18n("unsupportedGeometryType",{'geomType':type}));}
+break;}}
+var bounds;var boxNodes=this.getElementsByTagNameNS(node,this.gmlns,"Box");for(i=0;i<boxNodes.length;++i){var boxNode=boxNodes[i];var box=this.parseGeometry["box"].apply(this,[boxNode]);var parentNode=boxNode.parentNode;var parentName=parentNode.localName||parentNode.nodeName.split(":").pop();if(parentName==="boundedBy"){bounds=box;}else{geometry=box.toGeometry();}}
+var attributes;if(this.extractAttributes){attributes=this.parseAttributes(node);}
+var feature=new OpenLayers.Feature.Vector(geometry,attributes);feature.bounds=bounds;feature.gml={featureType:node.firstChild.nodeName.split(":")[1],featureNS:node.firstChild.namespaceURI,featureNSPrefix:node.firstChild.prefix};var childNode=node.firstChild;var fid;while(childNode){if(childNode.nodeType==1){fid=childNode.getAttribute("fid")||childNode.getAttribute("id");if(fid){break;}}
+childNode=childNode.nextSibling;}
+feature.fid=fid;return feature;},parseGeometry:{point:function(node){var nodeList,coordString;var coords=[];var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"pos");if(nodeList.length>0){coordString=nodeList[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);}
+if(coords.length==0){nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coordinates");if(nodeList.length>0){coordString=nodeList[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.removeSpace,"");coords=coordString.split(",");}}
+if(coords.length==0){nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coord");if(nodeList.length>0){var xList=this.getElementsByTagNameNS(nodeList[0],this.gmlns,"X");var yList=this.getElementsByTagNameNS(nodeList[0],this.gmlns,"Y");if(xList.length>0&&yList.length>0){coords=[xList[0].firstChild.nodeValue,yList[0].firstChild.nodeValue];}}}
+if(coords.length==2){coords[2]=null;}
+if(this.xy){return new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}
+else{return new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}},multipoint:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"Point");var components=[];if(nodeList.length>0){var point;for(var i=0;i<nodeList.length;++i){point=this.parseGeometry.point.apply(this,[nodeList[i]]);if(point){components.push(point);}}}
+return new OpenLayers.Geometry.MultiPoint(components);},linestring:function(node,ring){var nodeList,coordString;var coords=[];var points=[];nodeList=this.getElementsByTagNameNS(node,this.gmlns,"posList");if(nodeList.length>0){coordString=this.getChildValue(nodeList[0]);coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);var dim=parseInt(nodeList[0].getAttribute("dimension"));var j,x,y,z;for(var i=0;i<coords.length/dim;++i){j=i*dim;x=coords[j];y=coords[j+1];z=(dim==2)?null:coords[j+2];if(this.xy){points.push(new OpenLayers.Geometry.Point(x,y,z));}else{points.push(new OpenLayers.Geometry.Point(y,x,z));}}}
+if(coords.length==0){nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coordinates");if(nodeList.length>0){coordString=this.getChildValue(nodeList[0]);coordString=coordString.replace(this.regExes.trimSpace,"");coordString=coordString.replace(this.regExes.trimComma,",");var pointList=coordString.split(this.regExes.splitSpace);for(var i=0;i<pointList.length;++i){coords=pointList[i].split(",");if(coords.length==2){coords[2]=null;}
+if(this.xy){points.push(new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]));}else{points.push(new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]));}}}}
+var line=null;if(points.length!=0){if(ring){line=new OpenLayers.Geometry.LinearRing(points);}else{line=new OpenLayers.Geometry.LineString(points);}}
+return line;},multilinestring:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"LineString");var components=[];if(nodeList.length>0){var line;for(var i=0;i<nodeList.length;++i){line=this.parseGeometry.linestring.apply(this,[nodeList[i]]);if(line){components.push(line);}}}
+return new OpenLayers.Geometry.MultiLineString(components);},polygon:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"LinearRing");var components=[];if(nodeList.length>0){var ring;for(var i=0;i<nodeList.length;++i){ring=this.parseGeometry.linestring.apply(this,[nodeList[i],true]);if(ring){components.push(ring);}}}
+return new OpenLayers.Geometry.Polygon(components);},multipolygon:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"Polygon");var components=[];if(nodeList.length>0){var polygon;for(var i=0;i<nodeList.length;++i){polygon=this.parseGeometry.polygon.apply(this,[nodeList[i]]);if(polygon){components.push(polygon);}}}
+return new OpenLayers.Geometry.MultiPolygon(components);},envelope:function(node){var components=[];var coordString;var envelope;var lpoint=this.getElementsByTagNameNS(node,this.gmlns,"lowerCorner");if(lpoint.length>0){var coords=[];if(lpoint.length>0){coordString=lpoint[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);}
+if(coords.length==2){coords[2]=null;}
+if(this.xy){var lowerPoint=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{var lowerPoint=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}}
+var upoint=this.getElementsByTagNameNS(node,this.gmlns,"upperCorner");if(upoint.length>0){var coords=[];if(upoint.length>0){coordString=upoint[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);}
+if(coords.length==2){coords[2]=null;}
+if(this.xy){var upperPoint=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{var upperPoint=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}}
+if(lowerPoint&&upperPoint){components.push(new OpenLayers.Geometry.Point(lowerPoint.x,lowerPoint.y));components.push(new OpenLayers.Geometry.Point(upperPoint.x,lowerPoint.y));components.push(new OpenLayers.Geometry.Point(upperPoint.x,upperPoint.y));components.push(new OpenLayers.Geometry.Point(lowerPoint.x,upperPoint.y));components.push(new OpenLayers.Geometry.Point(lowerPoint.x,lowerPoint.y));var ring=new OpenLayers.Geometry.LinearRing(components);envelope=new OpenLayers.Geometry.Polygon([ring]);}
+return envelope;},box:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coordinates");var coordString;var coords,beginPoint=null,endPoint=null;if(nodeList.length>0){coordString=nodeList[0].firstChild.nodeValue;coords=coordString.split(" ");if(coords.length==2){beginPoint=coords[0].split(",");endPoint=coords[1].split(",");}}
+if(beginPoint!==null&&endPoint!==null){return new OpenLayers.Bounds(parseFloat(beginPoint[0]),parseFloat(beginPoint[1]),parseFloat(endPoint[0]),parseFloat(endPoint[1]));}}},parseAttributes:function(node){var attributes={};var childNode=node.firstChild;var children,i,child,grandchildren,grandchild,name,value;while(childNode){if(childNode.nodeType==1){children=childNode.childNodes;for(i=0;i<children.length;++i){child=children[i];if(child.nodeType==1){grandchildren=child.childNodes;if(grandchildren.length==1){grandchild=grandchildren[0];if(grandchild.nodeType==3||grandchild.nodeType==4){name=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;value=grandchild.nodeValue.replace(this.regExes.trimSpace,"");attributes[name]=value;}}else{attributes[child.nodeName.split(":").pop()]=null;}}}
+break;}
+childNode=childNode.nextSibling;}
+return attributes;},write:function(features){if(!(features instanceof Array)){features=[features];}
+var gml=this.createElementNS("http://www.opengis.net/wfs","wfs:"+this.collectionName);for(var i=0;i<features.length;i++){gml.appendChild(this.createFeatureXML(features[i]));}
+return OpenLayers.Format.XML.prototype.write.apply(this,[gml]);},createFeatureXML:function(feature){var geometry=feature.geometry;var geometryNode=this.buildGeometryNode(geometry);var geomContainer=this.createElementNS(this.featureNS,this.featurePrefix+":"+
+this.geometryName);geomContainer.appendChild(geometryNode);var featureNode=this.createElementNS(this.gmlns,"gml:"+this.featureName);var featureContainer=this.createElementNS(this.featureNS,this.featurePrefix+":"+
+this.layerName);var fid=feature.fid||feature.id;featureContainer.setAttribute("fid",fid);featureContainer.appendChild(geomContainer);for(var attr in feature.attributes){var attrText=this.createTextNode(feature.attributes[attr]);var nodename=attr.substring(attr.lastIndexOf(":")+1);var attrContainer=this.createElementNS(this.featureNS,this.featurePrefix+":"+
+nodename);attrContainer.appendChild(attrText);featureContainer.appendChild(attrContainer);}
+featureNode.appendChild(featureContainer);return featureNode;},buildGeometryNode:function(geometry){if(this.externalProjection&&this.internalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
+var className=geometry.CLASS_NAME;var type=className.substring(className.lastIndexOf(".")+1);var builder=this.buildGeometry[type.toLowerCase()];return builder.apply(this,[geometry]);},buildGeometry:{point:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:Point");gml.appendChild(this.buildCoordinatesNode(geometry));return gml;},multipoint:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:MultiPoint");var points=geometry.components;var pointMember,pointGeom;for(var i=0;i<points.length;i++){pointMember=this.createElementNS(this.gmlns,"gml:pointMember");pointGeom=this.buildGeometry.point.apply(this,[points[i]]);pointMember.appendChild(pointGeom);gml.appendChild(pointMember);}
+return gml;},linestring:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:LineString");gml.appendChild(this.buildCoordinatesNode(geometry));return gml;},multilinestring:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:MultiLineString");var lines=geometry.components;var lineMember,lineGeom;for(var i=0;i<lines.length;++i){lineMember=this.createElementNS(this.gmlns,"gml:lineStringMember");lineGeom=this.buildGeometry.linestring.apply(this,[lines[i]]);lineMember.appendChild(lineGeom);gml.appendChild(lineMember);}
+return gml;},linearring:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:LinearRing");gml.appendChild(this.buildCoordinatesNode(geometry));return gml;},polygon:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:Polygon");var rings=geometry.components;var ringMember,ringGeom,type;for(var i=0;i<rings.length;++i){type=(i==0)?"outerBoundaryIs":"innerBoundaryIs";ringMember=this.createElementNS(this.gmlns,"gml:"+type);ringGeom=this.buildGeometry.linearring.apply(this,[rings[i]]);ringMember.appendChild(ringGeom);gml.appendChild(ringMember);}
+return gml;},multipolygon:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:MultiPolygon");var polys=geometry.components;var polyMember,polyGeom;for(var i=0;i<polys.length;++i){polyMember=this.createElementNS(this.gmlns,"gml:polygonMember");polyGeom=this.buildGeometry.polygon.apply(this,[polys[i]]);polyMember.appendChild(polyGeom);gml.appendChild(polyMember);}
+return gml;},bounds:function(bounds){var gml=this.createElementNS(this.gmlns,"gml:Box");gml.appendChild(this.buildCoordinatesNode(bounds));return gml;}},buildCoordinatesNode:function(geometry){var coordinatesNode=this.createElementNS(this.gmlns,"gml:coordinates");coordinatesNode.setAttribute("decimal",".");coordinatesNode.setAttribute("cs",",");coordinatesNode.setAttribute("ts"," ");var parts=[];if(geometry instanceof OpenLayers.Bounds){parts.push(geometry.left+","+geometry.bottom);parts.push(geometry.right+","+geometry.top);}else{var points=(geometry.components)?geometry.components:[geometry];for(var i=0;i<points.length;i++){parts.push(points[i].x+","+points[i].y);}}
+var txtNode=this.createTextNode(parts.join(" "));coordinatesNode.appendChild(txtNode);return coordinatesNode;},CLASS_NAME:"OpenLayers.Format.GML"});OpenLayers.Format.GeoJSON=OpenLayers.Class(OpenLayers.Format.JSON,{ignoreExtraDims:false,initialize:function(options){OpenLayers.Format.JSON.prototype.initialize.apply(this,[options]);},read:function(json,type,filter){type=(type)?type:"FeatureCollection";var results=null;var obj=null;if(typeof json=="string"){obj=OpenLayers.Format.JSON.prototype.read.apply(this,[json,filter]);}else{obj=json;}
+if(!obj){OpenLayers.Console.error("Bad JSON: "+json);}else if(typeof(obj.type)!="string"){OpenLayers.Console.error("Bad GeoJSON - no type: "+json);}else if(this.isValidType(obj,type)){switch(type){case"Geometry":try{results=this.parseGeometry(obj);}catch(err){OpenLayers.Console.error(err);}
+break;case"Feature":try{results=this.parseFeature(obj);results.type="Feature";}catch(err){OpenLayers.Console.error(err);}
+break;case"FeatureCollection":results=[];switch(obj.type){case"Feature":try{results.push(this.parseFeature(obj));}catch(err){results=null;OpenLayers.Console.error(err);}
+break;case"FeatureCollection":for(var i=0,len=obj.features.length;i<len;++i){try{results.push(this.parseFeature(obj.features[i]));}catch(err){results=null;OpenLayers.Console.error(err);}}
+break;default:try{var geom=this.parseGeometry(obj);results.push(new OpenLayers.Feature.Vector(geom));}catch(err){results=null;OpenLayers.Console.error(err);}}
+break;}}
+return results;},isValidType:function(obj,type){var valid=false;switch(type){case"Geometry":if(OpenLayers.Util.indexOf(["Point","MultiPoint","LineString","MultiLineString","Polygon","MultiPolygon","Box","GeometryCollection"],obj.type)==-1){OpenLayers.Console.error("Unsupported geometry type: "+
+obj.type);}else{valid=true;}
+break;case"FeatureCollection":valid=true;break;default:if(obj.type==type){valid=true;}else{OpenLayers.Console.error("Cannot convert types from "+
+obj.type+" to "+type);}}
+return valid;},parseFeature:function(obj){var feature,geometry,attributes,bbox;attributes=(obj.properties)?obj.properties:{};bbox=(obj.geometry&&obj.geometry.bbox)||obj.bbox;try{geometry=this.parseGeometry(obj.geometry);}catch(err){throw err;}
+feature=new OpenLayers.Feature.Vector(geometry,attributes);if(bbox){feature.bounds=OpenLayers.Bounds.fromArray(bbox);}
+if(obj.id){feature.fid=obj.id;}
+return feature;},parseGeometry:function(obj){if(obj==null){return null;}
+var geometry,collection=false;if(obj.type=="GeometryCollection"){if(!(obj.geometries instanceof Array)){throw"GeometryCollection must have geometries array: "+obj;}
+var numGeom=obj.geometries.length;var components=new Array(numGeom);for(var i=0;i<numGeom;++i){components[i]=this.parseGeometry.apply(this,[obj.geometries[i]]);}
+geometry=new OpenLayers.Geometry.Collection(components);collection=true;}else{if(!(obj.coordinates instanceof Array)){throw"Geometry must have coordinates array: "+obj;}
+if(!this.parseCoords[obj.type.toLowerCase()]){throw"Unsupported geometry type: "+obj.type;}
+try{geometry=this.parseCoords[obj.type.toLowerCase()].apply(this,[obj.coordinates]);}catch(err){throw err;}}
+if(this.internalProjection&&this.externalProjection&&!collection){geometry.transform(this.externalProjection,this.internalProjection);}
+return geometry;},parseCoords:{"point":function(array){if(this.ignoreExtraDims==false&&array.length!=2){throw"Only 2D points are supported: "+array;}
+return new OpenLayers.Geometry.Point(array[0],array[1]);},"multipoint":function(array){var points=[];var p=null;for(var i=0,len=array.length;i<len;++i){try{p=this.parseCoords["point"].apply(this,[array[i]]);}catch(err){throw err;}
+points.push(p);}
+return new OpenLayers.Geometry.MultiPoint(points);},"linestring":function(array){var points=[];var p=null;for(var i=0,len=array.length;i<len;++i){try{p=this.parseCoords["point"].apply(this,[array[i]]);}catch(err){throw err;}
+points.push(p);}
+return new OpenLayers.Geometry.LineString(points);},"multilinestring":function(array){var lines=[];var l=null;for(var i=0,len=array.length;i<len;++i){try{l=this.parseCoords["linestring"].apply(this,[array[i]]);}catch(err){throw err;}
+lines.push(l);}
+return new OpenLayers.Geometry.MultiLineString(lines);},"polygon":function(array){var rings=[];var r,l;for(var i=0,len=array.length;i<len;++i){try{l=this.parseCoords["linestring"].apply(this,[array[i]]);}catch(err){throw err;}
+r=new OpenLayers.Geometry.LinearRing(l.components);rings.push(r);}
+return new OpenLayers.Geometry.Polygon(rings);},"multipolygon":function(array){var polys=[];var p=null;for(var i=0,len=array.length;i<len;++i){try{p=this.parseCoords["polygon"].apply(this,[array[i]]);}catch(err){throw err;}
+polys.push(p);}
+return new OpenLayers.Geometry.MultiPolygon(polys);},"box":function(array){if(array.length!=2){throw"GeoJSON box coordinates must have 2 elements";}
+return new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([new OpenLayers.Geometry.Point(array[0][0],array[0][1]),new OpenLayers.Geometry.Point(array[1][0],array[0][1]),new OpenLayers.Geometry.Point(array[1][0],array[1][1]),new OpenLayers.Geometry.Point(array[0][0],array[1][1]),new OpenLayers.Geometry.Point(array[0][0],array[0][1])])]);}},write:function(obj,pretty){var geojson={"type":null};if(obj instanceof Array){geojson.type="FeatureCollection";var numFeatures=obj.length;geojson.features=new Array(numFeatures);for(var i=0;i<numFeatures;++i){var element=obj[i];if(!element instanceof OpenLayers.Feature.Vector){var msg="FeatureCollection only supports collections "+"of features: "+element;throw msg;}
+geojson.features[i]=this.extract.feature.apply(this,[element]);}}else if(obj.CLASS_NAME.indexOf("OpenLayers.Geometry")==0){geojson=this.extract.geometry.apply(this,[obj]);}else if(obj instanceof OpenLayers.Feature.Vector){geojson=this.extract.feature.apply(this,[obj]);if(obj.layer&&obj.layer.projection){geojson.crs=this.createCRSObject(obj);}}
+return OpenLayers.Format.JSON.prototype.write.apply(this,[geojson,pretty]);},createCRSObject:function(object){var proj=object.layer.projection.toString();var crs={};if(proj.match(/epsg:/i)){var code=parseInt(proj.substring(proj.indexOf(":")+1));if(code==4326){crs={"type":"OGC","properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}};}else{crs={"type":"EPSG","properties":{"code":code}};}}
+return crs;},extract:{'feature':function(feature){var geom=this.extract.geometry.apply(this,[feature.geometry]);return{"type":"Feature","id":feature.fid==null?feature.id:feature.fid,"properties":feature.attributes,"geometry":geom};},'geometry':function(geometry){if(geometry==null){return null;}
+if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
+var geometryType=geometry.CLASS_NAME.split('.')[2];var data=this.extract[geometryType.toLowerCase()].apply(this,[geometry]);var json;if(geometryType=="Collection"){json={"type":"GeometryCollection","geometries":data};}else{json={"type":geometryType,"coordinates":data};}
+return json;},'point':function(point){return[point.x,point.y];},'multipoint':function(multipoint){var array=[];for(var i=0,len=multipoint.components.length;i<len;++i){array.push(this.extract.point.apply(this,[multipoint.components[i]]));}
+return array;},'linestring':function(linestring){var array=[];for(var i=0,len=linestring.components.length;i<len;++i){array.push(this.extract.point.apply(this,[linestring.components[i]]));}
+return array;},'multilinestring':function(multilinestring){var array=[];for(var i=0,len=multilinestring.components.length;i<len;++i){array.push(this.extract.linestring.apply(this,[multilinestring.components[i]]));}
+return array;},'polygon':function(polygon){var array=[];for(var i=0,len=polygon.components.length;i<len;++i){array.push(this.extract.linestring.apply(this,[polygon.components[i]]));}
+return array;},'multipolygon':function(multipolygon){var array=[];for(var i=0,len=multipolygon.components.length;i<len;++i){array.push(this.extract.polygon.apply(this,[multipolygon.components[i]]));}
+return array;},'collection':function(collection){var len=collection.components.length;var array=new Array(len);for(var i=0;i<len;++i){array[i]=this.extract.geometry.apply(this,[collection.components[i]]);}
+return array;}},CLASS_NAME:"OpenLayers.Format.GeoJSON"});OpenLayers.Format.ArcXML.Features=OpenLayers.Class(OpenLayers.Format.XML,{initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){var axl=new OpenLayers.Format.ArcXML();var parsed=axl.read(data);return parsed.features.feature;}});if(!OpenLayers.Format.GML){OpenLayers.Format.GML={};}
+OpenLayers.Format.GML.Base=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",wfs:"http://www.opengis.net/wfs"},defaultPrefix:"gml",schemaLocation:null,featureType:null,featureNS:null,geometryName:"geometry",extractAttributes:true,srsName:null,xy:true,geometryTypes:null,singleFeatureType:null,regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.setGeometryTypes();if(options&&options.featureNS){this.setNamespace("feature",options.featureNS);}
+this.singleFeatureType=!options||(typeof options.featureType==="string");},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+if(data&&data.nodeType==9){data=data.documentElement;}
+var features=[];this.readNode(data,{features:features});if(features.length==0){var elements=this.getElementsByTagNameNS(data,this.namespaces.gml,"featureMember");if(elements.length){for(var i=0,len=elements.length;i<len;++i){this.readNode(elements[i],{features:features});}}else{var elements=this.getElementsByTagNameNS(data,this.namespaces.gml,"featureMembers");if(elements.length){this.readNode(elements[0],{features:features});}}}
+return features;},readers:{"gml":{"featureMember":function(node,obj){this.readChildNodes(node,obj);},"featureMembers":function(node,obj){this.readChildNodes(node,obj);},"name":function(node,obj){obj.name=this.getChildValue(node);},"boundedBy":function(node,obj){var container={};this.readChildNodes(node,container);if(container.components&&container.components.length>0){obj.bounds=container.components[0];}},"Point":function(node,container){var obj={points:[]};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
+container.components.push(obj.points[0]);},"coordinates":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");str=str.replace(this.regExes.trimComma,",");var pointList=str.split(this.regExes.splitSpace);var coords;var numPoints=pointList.length;var points=new Array(numPoints);for(var i=0;i<numPoints;++i){coords=pointList[i].split(",");if(this.xy){points[i]=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{points[i]=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}}
+obj.points=points;},"coord":function(node,obj){var coord={};this.readChildNodes(node,coord);if(!obj.points){obj.points=[];}
+obj.points.push(new OpenLayers.Geometry.Point(coord.x,coord.y,coord.z));},"X":function(node,coord){coord.x=this.getChildValue(node);},"Y":function(node,coord){coord.y=this.getChildValue(node);},"Z":function(node,coord){coord.z=this.getChildValue(node);},"MultiPoint":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.MultiPoint(obj.components)];},"pointMember":function(node,obj){this.readChildNodes(node,obj);},"LineString":function(node,container){var obj={};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
+container.components.push(new OpenLayers.Geometry.LineString(obj.points));},"MultiLineString":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.MultiLineString(obj.components)];},"lineStringMember":function(node,obj){this.readChildNodes(node,obj);},"Polygon":function(node,container){var obj={outer:null,inner:[]};this.readChildNodes(node,obj);obj.inner.unshift(obj.outer);if(!container.components){container.components=[];}
+container.components.push(new OpenLayers.Geometry.Polygon(obj.inner));},"LinearRing":function(node,obj){var container={};this.readChildNodes(node,container);obj.components=[new OpenLayers.Geometry.LinearRing(container.points)];},"MultiPolygon":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.MultiPolygon(obj.components)];},"polygonMember":function(node,obj){this.readChildNodes(node,obj);},"GeometryCollection":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.Collection(obj.components)];},"geometryMember":function(node,obj){this.readChildNodes(node,obj);}},"feature":{"*":function(node,obj){var name;var local=node.localName||node.nodeName.split(":").pop();if(obj.features){if(!this.singleFeatureType&&(OpenLayers.Util.indexOf(this.featureType,local)!==-1)){name="_typeName";}else if(local===this.featureType){name="_typeName";}}else{if(node.childNodes.length==0||(node.childNodes.length==1&&node.firstChild.nodeType==3)){if(this.extractAttributes){name="_attribute";}}else{name="_geometry";}}
+if(name){this.readers.feature[name].apply(this,[node,obj]);}},"_typeName":function(node,obj){var container={components:[],attributes:{}};this.readChildNodes(node,container);if(container.name){container.attributes.name=container.name;}
+var feature=new OpenLayers.Feature.Vector(container.components[0],container.attributes);if(!this.singleFeatureType){feature.type=node.nodeName.split(":").pop();feature.namespace=node.namespaceURI;}
+var fid=node.getAttribute("fid")||this.getAttributeNS(node,this.namespaces["gml"],"id");if(fid){feature.fid=fid;}
+if(this.internalProjection&&this.externalProjection&&feature.geometry){feature.geometry.transform(this.externalProjection,this.internalProjection);}
+if(container.bounds){feature.bounds=container.bounds;}
+obj.features.push(feature);},"_geometry":function(node,obj){this.readChildNodes(node,obj);},"_attribute":function(node,obj){var local=node.localName||node.nodeName.split(":").pop();var value=this.getChildValue(node);obj.attributes[local]=value;}},"wfs":{"FeatureCollection":function(node,obj){this.readChildNodes(node,obj);}}},write:function(features){var name;if(features instanceof Array){name="featureMembers";}else{name="featureMember";}
+var root=this.writeNode("gml:"+name,features);this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},writers:{"gml":{"featureMember":function(feature){var node=this.createElementNSPlus("gml:featureMember");this.writeNode("feature:_typeName",feature,node);return node;},"MultiPoint":function(geometry){var node=this.createElementNSPlus("gml:MultiPoint");for(var i=0;i<geometry.components.length;++i){this.writeNode("pointMember",geometry.components[i],node);}
+return node;},"pointMember":function(geometry){var node=this.createElementNSPlus("gml:pointMember");this.writeNode("Point",geometry,node);return node;},"MultiLineString":function(geometry){var node=this.createElementNSPlus("gml:MultiLineString");for(var i=0;i<geometry.components.length;++i){this.writeNode("lineStringMember",geometry.components[i],node);}
+return node;},"lineStringMember":function(geometry){var node=this.createElementNSPlus("gml:lineStringMember");this.writeNode("LineString",geometry,node);return node;},"MultiPolygon":function(geometry){var node=this.createElementNSPlus("gml:MultiPolygon");for(var i=0;i<geometry.components.length;++i){this.writeNode("polygonMember",geometry.components[i],node);}
+return node;},"polygonMember":function(geometry){var node=this.createElementNSPlus("gml:polygonMember");this.writeNode("Polygon",geometry,node);return node;},"GeometryCollection":function(geometry){var node=this.createElementNSPlus("gml:GeometryCollection");for(var i=0,len=geometry.components.length;i<len;++i){this.writeNode("geometryMember",geometry.components[i],node);}
+return node;},"geometryMember":function(geometry){var node=this.createElementNSPlus("gml:geometryMember");var child=this.writeNode("feature:_geometry",geometry);node.appendChild(child.firstChild);return node;}},"feature":{"_typeName":function(feature){var node=this.createElementNSPlus("feature:"+this.featureType,{attributes:{fid:feature.fid}});if(feature.geometry){this.writeNode("feature:_geometry",feature.geometry,node);}
+for(var name in feature.attributes){var value=feature.attributes[name];if(value!=null){this.writeNode("feature:_attribute",{name:name,value:value},node);}}
+return node;},"_geometry":function(geometry){if(this.externalProjection&&this.internalProjection){geometry=geometry.clone().transform(this.internalProjection,this.externalProjection);}
+var node=this.createElementNSPlus("feature:"+this.geometryName);var type=this.geometryTypes[geometry.CLASS_NAME];var child=this.writeNode("gml:"+type,geometry,node);if(this.srsName){child.setAttribute("srsName",this.srsName);}
+return node;},"_attribute":function(obj){return this.createElementNSPlus("feature:"+obj.name,{value:obj.value});}},"wfs":{"FeatureCollection":function(features){var node=this.createElementNSPlus("wfs:FeatureCollection");for(var i=0,len=features.length;i<len;++i){this.writeNode("gml:featureMember",features[i],node);}
+return node;}}},setGeometryTypes:function(){this.geometryTypes={"OpenLayers.Geometry.Point":"Point","OpenLayers.Geometry.MultiPoint":"MultiPoint","OpenLayers.Geometry.LineString":"LineString","OpenLayers.Geometry.MultiLineString":"MultiLineString","OpenLayers.Geometry.Polygon":"Polygon","OpenLayers.Geometry.MultiPolygon":"MultiPolygon","OpenLayers.Geometry.Collection":"GeometryCollection"};},CLASS_NAME:"OpenLayers.Format.GML.Base"});OpenLayers.Format.WFS=OpenLayers.Class(OpenLayers.Format.GML,{layer:null,wfsns:"http://www.opengis.net/wfs",ogcns:"http://www.opengis.net/ogc",initialize:function(options,layer){OpenLayers.Format.GML.prototype.initialize.apply(this,[options]);this.layer=layer;if(this.layer.featureNS){this.featureNS=this.layer.featureNS;}
+if(this.layer.options.geometry_column){this.geometryName=this.layer.options.geometry_column;}
+if(this.layer.options.typename){this.featureName=this.layer.options.typename;}},write:function(features){var transaction=this.createElementNS(this.wfsns,'wfs:Transaction');transaction.setAttribute("version","1.0.0");transaction.setAttribute("service","WFS");for(var i=0;i<features.length;i++){switch(features[i].state){case OpenLayers.State.INSERT:transaction.appendChild(this.insert(features[i]));break;case OpenLayers.State.UPDATE:transaction.appendChild(this.update(features[i]));break;case OpenLayers.State.DELETE:transaction.appendChild(this.remove(features[i]));break;}}
+return OpenLayers.Format.XML.prototype.write.apply(this,[transaction]);},createFeatureXML:function(feature){var geometryNode=this.buildGeometryNode(feature.geometry);var geomContainer=this.createElementNS(this.featureNS,"feature:"+this.geometryName);geomContainer.appendChild(geometryNode);var featureContainer=this.createElementNS(this.featureNS,"feature:"+this.featureName);featureContainer.appendChild(geomContainer);for(var attr in feature.attributes){var attrText=this.createTextNode(feature.attributes[attr]);var nodename=attr;if(attr.search(":")!=-1){nodename=attr.split(":")[1];}
+var attrContainer=this.createElementNS(this.featureNS,"feature:"+nodename);attrContainer.appendChild(attrText);featureContainer.appendChild(attrContainer);}
+return featureContainer;},insert:function(feature){var insertNode=this.createElementNS(this.wfsns,'wfs:Insert');insertNode.appendChild(this.createFeatureXML(feature));return insertNode;},update:function(feature){if(!feature.fid){OpenLayers.Console.userError(OpenLayers.i18n("noFID"));}
+var updateNode=this.createElementNS(this.wfsns,'wfs:Update');updateNode.setAttribute("typeName",this.featurePrefix+':'+this.featureName);updateNode.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);var propertyNode=this.createElementNS(this.wfsns,'wfs:Property');var nameNode=this.createElementNS(this.wfsns,'wfs:Name');var txtNode=this.createTextNode(this.geometryName);nameNode.appendChild(txtNode);propertyNode.appendChild(nameNode);var valueNode=this.createElementNS(this.wfsns,'wfs:Value');var geometryNode=this.buildGeometryNode(feature.geometry);if(feature.layer){geometryNode.setAttribute("srsName",feature.layer.projection.getCode());}
+valueNode.appendChild(geometryNode);propertyNode.appendChild(valueNode);updateNode.appendChild(propertyNode);for(var propName in feature.attributes){propertyNode=this.createElementNS(this.wfsns,'wfs:Property');nameNode=this.createElementNS(this.wfsns,'wfs:Name');nameNode.appendChild(this.createTextNode(propName));propertyNode.appendChild(nameNode);valueNode=this.createElementNS(this.wfsns,'wfs:Value');valueNode.appendChild(this.createTextNode(feature.attributes[propName]));propertyNode.appendChild(valueNode);updateNode.appendChild(propertyNode);}
+var filterNode=this.createElementNS(this.ogcns,'ogc:Filter');var filterIdNode=this.createElementNS(this.ogcns,'ogc:FeatureId');filterIdNode.setAttribute("fid",feature.fid);filterNode.appendChild(filterIdNode);updateNode.appendChild(filterNode);return updateNode;},remove:function(feature){if(!feature.fid){OpenLayers.Console.userError(OpenLayers.i18n("noFID"));return false;}
+var deleteNode=this.createElementNS(this.wfsns,'wfs:Delete');deleteNode.setAttribute("typeName",this.featurePrefix+':'+this.featureName);deleteNode.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);var filterNode=this.createElementNS(this.ogcns,'ogc:Filter');var filterIdNode=this.createElementNS(this.ogcns,'ogc:FeatureId');filterIdNode.setAttribute("fid",feature.fid);filterNode.appendChild(filterIdNode);deleteNode.appendChild(filterNode);return deleteNode;},destroy:function(){this.layer=null;},CLASS_NAME:"OpenLayers.Format.WFS"});OpenLayers.Layer.ArcIMS=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{ClientVersion:"9.2",ServiceName:''},tileSize:null,featureCoordSys:"4326",filterCoordSys:"4326",layers:null,async:true,name:"ArcIMS",isBaseLayer:true,DEFAULT_OPTIONS:{tileSize:new OpenLayers.Size(512,512),featureCoordSys:"4326",filterCoordSys:"4326",layers:null,isBaseLayer:true,async:true,name:"ArcIMS"},initialize:function(name,url,options){this.tileSize=new OpenLayers.Size(512,512);this.params=OpenLayers.Util.applyDefaults({ServiceName:options.serviceName},this.DEFAULT_PARAMS);this.options=OpenLayers.Util.applyDefaults(options,this.DEFAULT_OPTIONS);OpenLayers.Layer.Grid.prototype.initialize.apply(this,[name,url,this.params,options]);if(this.transparent){if(!this.isBaseLayer){this.isBaseLayer=false;}
+if(this.format=="image/jpeg"){this.format=OpenLayers.Util.alphaHack()?"image/gif":"image/png";}}
+if(this.options.layers===null){this.options.layers=[];}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},getURL:function(bounds){var url="";bounds=this.adjustBounds(bounds);var axlReq=new OpenLayers.Format.ArcXML(OpenLayers.Util.extend(this.options,{requesttype:"image",envelope:bounds.toArray(),tileSize:this.tileSize}));var req=new OpenLayers.Request.POST({url:this.getFullRequestString(),data:axlReq.write(),async:false});if(req!=null){var doc=req.responseXML;if(!doc||!doc.documentElement){doc=req.responseText;}
+var axlResp=new OpenLayers.Format.ArcXML();var arcxml=axlResp.read(doc);url=this.getUrlOrImage(arcxml.image.output);}
+return url;},getURLasync:function(bounds,scope,prop,callback){bounds=this.adjustBounds(bounds);var axlReq=new OpenLayers.Format.ArcXML(OpenLayers.Util.extend(this.options,{requesttype:"image",envelope:bounds.toArray(),tileSize:this.tileSize}));OpenLayers.Request.POST({url:this.getFullRequestString(),async:true,data:axlReq.write(),callback:function(req){var doc=req.responseXML;if(!doc||!doc.documentElement){doc=req.responseText;}
+var axlResp=new OpenLayers.Format.ArcXML();var arcxml=axlResp.read(doc);scope[prop]=this.getUrlOrImage(arcxml.image.output);callback.apply(scope);},scope:this});},getUrlOrImage:function(output){var ret="";if(output.url){ret=output.url;}else if(output.data){ret="data:image/"+output.type+";base64,"+output.data;}
+return ret;},setLayerQuery:function(id,querydef){for(var lyr=0;lyr<this.options.layers.length;lyr++){if(id==this.options.layers[lyr].id){this.options.layers[lyr].query=querydef;return;}}
+this.options.layers.push({id:id,visible:true,query:querydef});},getFeatureInfo:function(geometry,layer,options){var buffer=options.buffer||1;var callback=options.callback||function(){};var scope=options.scope||window;var requestOptions={};OpenLayers.Util.extend(requestOptions,this.options);requestOptions.requesttype="feature";if(geometry instanceof OpenLayers.LonLat){requestOptions.polygon=null;requestOptions.envelope=[geometry.lon-buffer,geometry.lat-buffer,geometry.lon+buffer,geometry.lat+buffer];}else if(geometry instanceof OpenLayers.Geometry.Polygon){requestOptions.envelope=null;requestOptions.polygon=geometry;}
+var arcxml=new OpenLayers.Format.ArcXML(requestOptions);OpenLayers.Util.extend(arcxml.request.get_feature,options);arcxml.request.get_feature.layer=layer.id;if(typeof layer.query.accuracy=="number"){arcxml.request.get_feature.query.accuracy=layer.query.accuracy;}else{var mapCenter=this.map.getCenter();var viewPx=this.map.getViewPortPxFromLonLat(mapCenter);viewPx.x++;var mapOffCenter=this.map.getLonLatFromPixel(viewPx);arcxml.request.get_feature.query.accuracy=mapOffCenter.lon-mapCenter.lon;}
+arcxml.request.get_feature.query.where=layer.query.where;arcxml.request.get_feature.query.spatialfilter.relation="area_intersection";OpenLayers.Request.POST({url:this.getFullRequestString({'CustomService':'Query'}),data:arcxml.write(),callback:function(request){var response=arcxml.parseResponse(request.responseText);if(!arcxml.iserror()){callback.call(scope,response.features);}else{callback.call(scope,null);}}});},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.ArcIMS(this.name,this.url,this.getOptions());}
+obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.ArcIMS"});OpenLayers.Format.GML.v2=OpenLayers.Class(OpenLayers.Format.GML.Base,{schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd",initialize:function(options){OpenLayers.Format.GML.Base.prototype.initialize.apply(this,[options]);},readers:{"gml":OpenLayers.Util.applyDefaults({"outerBoundaryIs":function(node,container){var obj={};this.readChildNodes(node,obj);container.outer=obj.components[0];},"innerBoundaryIs":function(node,container){var obj={};this.readChildNodes(node,obj);container.inner.push(obj.components[0]);},"Box":function(node,container){var obj={};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
+var min=obj.points[0];var max=obj.points[1];container.components.push(new OpenLayers.Bounds(min.x,min.y,max.x,max.y));}},OpenLayers.Format.GML.Base.prototype.readers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.readers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.readers["wfs"]},write:function(features){var name;if(features instanceof Array){name="wfs:FeatureCollection";}else{name="gml:featureMember";}
+var root=this.writeNode(name,features);this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},writers:{"gml":OpenLayers.Util.applyDefaults({"Point":function(geometry){var node=this.createElementNSPlus("gml:Point");this.writeNode("coordinates",[geometry],node);return node;},"coordinates":function(points){var numPoints=points.length;var parts=new Array(numPoints);var point;for(var i=0;i<numPoints;++i){point=points[i];if(this.xy){parts[i]=point.x+","+point.y;}else{parts[i]=point.y+","+point.x;}
+if(point.z!=undefined){parts[i]+=","+point.z;}}
+return this.createElementNSPlus("gml:coordinates",{attributes:{decimal:".",cs:",",ts:" "},value:(numPoints==1)?parts[0]:parts.join(" ")});},"LineString":function(geometry){var node=this.createElementNSPlus("gml:LineString");this.writeNode("coordinates",geometry.components,node);return node;},"Polygon":function(geometry){var node=this.createElementNSPlus("gml:Polygon");this.writeNode("outerBoundaryIs",geometry.components[0],node);for(var i=1;i<geometry.components.length;++i){this.writeNode("innerBoundaryIs",geometry.components[i],node);}
+return node;},"outerBoundaryIs":function(ring){var node=this.createElementNSPlus("gml:outerBoundaryIs");this.writeNode("LinearRing",ring,node);return node;},"innerBoundaryIs":function(ring){var node=this.createElementNSPlus("gml:innerBoundaryIs");this.writeNode("LinearRing",ring,node);return node;},"LinearRing":function(ring){var node=this.createElementNSPlus("gml:LinearRing");this.writeNode("coordinates",ring.components,node);return node;},"Box":function(bounds){var node=this.createElementNSPlus("gml:Box");this.writeNode("coordinates",[{x:bounds.left,y:bounds.bottom},{x:bounds.right,y:bounds.top}],node);if(this.srsName){node.setAttribute("srsName",this.srsName);}
+return node;}},OpenLayers.Format.GML.Base.prototype.writers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.writers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.writers["wfs"]},CLASS_NAME:"OpenLayers.Format.GML.v2"});OpenLayers.Format.GML.v3=OpenLayers.Class(OpenLayers.Format.GML.Base,{schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/1.0.0/gmlsf.xsd",curve:false,multiCurve:true,surface:false,multiSurface:true,initialize:function(options){OpenLayers.Format.GML.Base.prototype.initialize.apply(this,[options]);},readers:{"gml":OpenLayers.Util.applyDefaults({"featureMembers":function(node,obj){this.readChildNodes(node,obj);},"Curve":function(node,container){var obj={points:[]};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
+container.components.push(new OpenLayers.Geometry.LineString(obj.points));},"segments":function(node,obj){this.readChildNodes(node,obj);},"LineStringSegment":function(node,container){var obj={};this.readChildNodes(node,obj);if(obj.points){Array.prototype.push.apply(container.points,obj.points);}},"pos":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");var coords=str.split(this.regExes.splitSpace);var point;if(this.xy){point=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{point=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}
+obj.points=[point];},"posList":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");var coords=str.split(this.regExes.splitSpace);var dim=parseInt(node.getAttribute("dimension"))||2;var j,x,y,z;var numPoints=coords.length/dim;var points=new Array(numPoints);for(var i=0,len=coords.length;i<len;i+=dim){x=coords[i];y=coords[i+1];z=(dim==2)?undefined:coords[i+2];if(this.xy){points[i/dim]=new OpenLayers.Geometry.Point(x,y,z);}else{points[i/dim]=new OpenLayers.Geometry.Point(y,x,z);}}
+obj.points=points;},"Surface":function(node,obj){this.readChildNodes(node,obj);},"patches":function(node,obj){this.readChildNodes(node,obj);},"PolygonPatch":function(node,obj){this.readers.gml.Polygon.apply(this,[node,obj]);},"exterior":function(node,container){var obj={};this.readChildNodes(node,obj);container.outer=obj.components[0];},"interior":function(node,container){var obj={};this.readChildNodes(node,obj);container.inner.push(obj.components[0]);},"MultiCurve":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);if(obj.components.length>0){container.components=[new OpenLayers.Geometry.MultiLineString(obj.components)];}},"curveMember":function(node,obj){this.readChildNodes(node,obj);},"MultiSurface":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);if(obj.components.length>0){container.components=[new OpenLayers.Geometry.MultiPolygon(obj.components)];}},"surfaceMember":function(node,obj){this.readChildNodes(node,obj);},"surfaceMembers":function(node,obj){this.readChildNodes(node,obj);},"pointMembers":function(node,obj){this.readChildNodes(node,obj);},"lineStringMembers":function(node,obj){this.readChildNodes(node,obj);},"polygonMembers":function(node,obj){this.readChildNodes(node,obj);},"geometryMembers":function(node,obj){this.readChildNodes(node,obj);},"Envelope":function(node,container){var obj={points:new Array(2)};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
+var min=obj.points[0];var max=obj.points[1];container.components.push(new OpenLayers.Bounds(min.x,min.y,max.x,max.y));},"lowerCorner":function(node,container){var obj={};this.readers.gml.pos.apply(this,[node,obj]);container.points[0]=obj.points[0];},"upperCorner":function(node,container){var obj={};this.readers.gml.pos.apply(this,[node,obj]);container.points[1]=obj.points[0];}},OpenLayers.Format.GML.Base.prototype.readers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.readers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.readers["wfs"]},write:function(features){var name;if(features instanceof Array){name="featureMembers";}else{name="featureMember";}
+var root=this.writeNode("gml:"+name,features);this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},writers:{"gml":OpenLayers.Util.applyDefaults({"featureMembers":function(features){var node=this.createElementNSPlus("gml:featureMembers");for(var i=0,len=features.length;i<len;++i){this.writeNode("feature:_typeName",features[i],node);}
+return node;},"Point":function(geometry){var node=this.createElementNSPlus("gml:Point");this.writeNode("pos",geometry,node);return node;},"pos":function(point){var pos=(this.xy)?(point.x+" "+point.y):(point.y+" "+point.x);return this.createElementNSPlus("gml:pos",{value:pos});},"LineString":function(geometry){var node=this.createElementNSPlus("gml:LineString");this.writeNode("posList",geometry.components,node);return node;},"Curve":function(geometry){var node=this.createElementNSPlus("gml:Curve");this.writeNode("segments",geometry,node);return node;},"segments":function(geometry){var node=this.createElementNSPlus("gml:segments");this.writeNode("LineStringSegment",geometry,node);return node;},"LineStringSegment":function(geometry){var node=this.createElementNSPlus("gml:LineStringSegment");this.writeNode("posList",geometry.components,node);return node;},"posList":function(points){var len=points.length;var parts=new Array(len);var point;for(var i=0;i<len;++i){point=points[i];if(this.xy){parts[i]=point.x+" "+point.y;}else{parts[i]=point.y+" "+point.x;}}
+return this.createElementNSPlus("gml:posList",{value:parts.join(" ")});},"Surface":function(geometry){var node=this.createElementNSPlus("gml:Surface");this.writeNode("patches",geometry,node);return node;},"patches":function(geometry){var node=this.createElementNSPlus("gml:patches");this.writeNode("PolygonPatch",geometry,node);return node;},"PolygonPatch":function(geometry){var node=this.createElementNSPlus("gml:PolygonPatch",{attributes:{interpolation:"planar"}});this.writeNode("exterior",geometry.components[0],node);for(var i=1,len=geometry.components.length;i<len;++i){this.writeNode("interior",geometry.components[i],node);}
+return node;},"Polygon":function(geometry){var node=this.createElementNSPlus("gml:Polygon");this.writeNode("exterior",geometry.components[0],node);for(var i=1,len=geometry.components.length;i<len;++i){this.writeNode("interior",geometry.components[i],node);}
+return node;},"exterior":function(ring){var node=this.createElementNSPlus("gml:exterior");this.writeNode("LinearRing",ring,node);return node;},"interior":function(ring){var node=this.createElementNSPlus("gml:interior");this.writeNode("LinearRing",ring,node);return node;},"LinearRing":function(ring){var node=this.createElementNSPlus("gml:LinearRing");this.writeNode("posList",ring.components,node);return node;},"MultiCurve":function(geometry){var node=this.createElementNSPlus("gml:MultiCurve");for(var i=0,len=geometry.components.length;i<len;++i){this.writeNode("curveMember",geometry.components[i],node);}
+return node;},"curveMember":function(geometry){var node=this.createElementNSPlus("gml:curveMember");if(this.curve){this.writeNode("Curve",geometry,node);}else{this.writeNode("LineString",geometry,node);}
+return node;},"MultiSurface":function(geometry){var node=this.createElementNSPlus("gml:MultiSurface");for(var i=0,len=geometry.components.length;i<len;++i){this.writeNode("surfaceMember",geometry.components[i],node);}
+return node;},"surfaceMember":function(polygon){var node=this.createElementNSPlus("gml:surfaceMember");if(this.surface){this.writeNode("Surface",polygon,node);}else{this.writeNode("Polygon",polygon,node);}
+return node;},"Envelope":function(bounds){var node=this.createElementNSPlus("gml:Envelope");this.writeNode("lowerCorner",bounds,node);this.writeNode("upperCorner",bounds,node);if(this.srsName){node.setAttribute("srsName",this.srsName);}
+return node;},"lowerCorner":function(bounds){var pos=(this.xy)?(bounds.left+" "+bounds.bottom):(bounds.bottom+" "+bounds.left);return this.createElementNSPlus("gml:lowerCorner",{value:pos});},"upperCorner":function(bounds){var pos=(this.xy)?(bounds.right+" "+bounds.top):(bounds.top+" "+bounds.right);return this.createElementNSPlus("gml:upperCorner",{value:pos});}},OpenLayers.Format.GML.Base.prototype.writers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.writers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.writers["wfs"]},setGeometryTypes:function(){this.geometryTypes={"OpenLayers.Geometry.Point":"Point","OpenLayers.Geometry.MultiPoint":"MultiPoint","OpenLayers.Geometry.LineString":(this.curve===true)?"Curve":"LineString","OpenLayers.Geometry.MultiLineString":(this.multiCurve===false)?"MultiLineString":"MultiCurve","OpenLayers.Geometry.Polygon":(this.surface===true)?"Surface":"Polygon","OpenLayers.Geometry.MultiPolygon":(this.multiSurface===false)?"MultiPolygon":"MultiSurface","OpenLayers.Geometry.Collection":"GeometryCollection"};},CLASS_NAME:"OpenLayers.Format.GML.v3"});OpenLayers.Format.Atom=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{atom:"http://www.w3.org/2005/Atom",georss:"http://www.georss.org/georss"},feedTitle:"untitled",defaultEntryTitle:"untitled",gmlParser:null,xy:false,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
+return this.parseFeatures(doc);},write:function(features){var doc;if(features instanceof Array){doc=this.createElementNSPlus("atom:feed");doc.appendChild(this.createElementNSPlus("atom:title",{value:this.feedTitle}));for(var i=0,ii=features.length;i<ii;i++){doc.appendChild(this.buildEntryNode(features[i]));}}
+else{doc=this.buildEntryNode(features);}
+return OpenLayers.Format.XML.prototype.write.apply(this,[doc]);},buildContentNode:function(content){var node=this.createElementNSPlus("atom:content",{attributes:{type:content.type||null}});if(content.src){node.setAttribute("src",content.src);}else{if(content.type=="text"||content.type==null){node.appendChild(this.createTextNode(content.value));}else if(content.type=="html"){if(typeof content.value!="string"){throw"HTML content must be in form of an escaped string";}
+node.appendChild(this.createTextNode(content.value));}else if(content.type=="xhtml"){node.appendChild(content.value);}else if(content.type=="xhtml"||content.type.match(/(\+|\/)xml$/)){node.appendChild(content.value);}
+else{node.appendChild(this.createTextNode(content.value));}}
+return node;},buildEntryNode:function(feature){var attrib=feature.attributes;var atomAttrib=attrib.atom||{};var entryNode=this.createElementNSPlus("atom:entry");if(atomAttrib.authors){var authors=atomAttrib.authors instanceof Array?atomAttrib.authors:[atomAttrib.authors];for(var i=0,ii=authors.length;i<ii;i++){entryNode.appendChild(this.buildPersonConstructNode("author",authors[i]));}}
+if(atomAttrib.categories){var categories=atomAttrib.categories instanceof Array?atomAttrib.categories:[atomAttrib.categories];var category;for(var i=0,ii=categories.length;i<ii;i++){category=categories[i];entryNode.appendChild(this.createElementNSPlus("atom:category",{attributes:{term:category.term,scheme:category.scheme||null,label:category.label||null}}));}}
+if(atomAttrib.content){entryNode.appendChild(this.buildContentNode(atomAttrib.content));}
+if(atomAttrib.contributors){var contributors=atomAttrib.contributors instanceof Array?atomAttrib.contributors:[atomAttrib.contributors];for(var i=0,ii=contributors.length;i<ii;i++){entryNode.appendChild(this.buildPersonConstructNode("contributor",contributors[i]));}}
+if(feature.fid){entryNode.appendChild(this.createElementNSPlus("atom:id",{value:feature.fid}));}
+if(atomAttrib.links){var links=atomAttrib.links instanceof Array?atomAttrib.links:[atomAttrib.links];var link;for(var i=0,ii=links.length;i<ii;i++){link=links[i];entryNode.appendChild(this.createElementNSPlus("atom:link",{attributes:{href:link.href,rel:link.rel||null,type:link.type||null,hreflang:link.hreflang||null,title:link.title||null,length:link.length||null}}));}}
+if(atomAttrib.published){entryNode.appendChild(this.createElementNSPlus("atom:published",{value:atomAttrib.published}));}
+if(atomAttrib.rights){entryNode.appendChild(this.createElementNSPlus("atom:rights",{value:atomAttrib.rights}));}
+if(atomAttrib.summary||attrib.description){entryNode.appendChild(this.createElementNSPlus("atom:summary",{value:atomAttrib.summary||attrib.description}));}
+entryNode.appendChild(this.createElementNSPlus("atom:title",{value:atomAttrib.title||attrib.title||this.defaultEntryTitle}));if(atomAttrib.updated){entryNode.appendChild(this.createElementNSPlus("atom:updated",{value:atomAttrib.updated}));}
+if(feature.geometry){var whereNode=this.createElementNSPlus("georss:where");whereNode.appendChild(this.buildGeometryNode(feature.geometry));entryNode.appendChild(whereNode);}
+return entryNode;},initGmlParser:function(){this.gmlParser=new OpenLayers.Format.GML.v3({xy:this.xy,featureNS:"http://example.com#feature",internalProjection:this.internalProjection,externalProjection:this.externalProjection});},buildGeometryNode:function(geometry){if(!this.gmlParser){this.initGmlParser();}
+var node=this.gmlParser.writeNode("feature:_geometry",geometry);return node.firstChild;},buildPersonConstructNode:function(name,value){var oNames=["uri","email"];var personNode=this.createElementNSPlus("atom:"+name);personNode.appendChild(this.createElementNSPlus("atom:name",{value:value.name}));for(var i=0,ii=oNames.length;i<ii;i++){if(value[oNames[i]]){personNode.appendChild(this.createElementNSPlus("atom:"+oNames[i],{value:value[oNames[i]]}));}}
+return personNode;},getFirstChildValue:function(node,nsuri,name,def){var value;var nodes=this.getElementsByTagNameNS(node,nsuri,name);if(nodes&&nodes.length>0){value=this.getChildValue(nodes[0],def);}else{value=def;}
+return value;},parseFeature:function(node){var atomAttrib={};var value=null;var nodes=null;var attval=null;var atomns=this.namespaces.atom;this.parsePersonConstructs(node,"author",atomAttrib);nodes=this.getElementsByTagNameNS(node,atomns,"category");if(nodes.length>0){atomAttrib.categories=[];}
+for(var i=0,ii=nodes.length;i<ii;i++){value={};value.term=nodes[i].getAttribute("term");attval=nodes[i].getAttribute("scheme");if(attval){value.scheme=attval;}
+attval=nodes[i].getAttribute("label");if(attval){value.label=attval;}
+atomAttrib.categories.push(value);}
+nodes=this.getElementsByTagNameNS(node,atomns,"content");if(nodes.length>0){value={};attval=nodes[0].getAttribute("type");if(attval){value.type=attval;}
+attval=nodes[0].getAttribute("src");if(attval){value.src=attval;}else{if(value.type=="text"||value.type=="html"||value.type==null){value.value=this.getFirstChildValue(node,atomns,"content",null);}else if(value.type=="xhtml"||value.type.match(/(\+|\/)xml$/)){value.value=this.getChildEl(nodes[0]);}else{value.value=this.getFirstChildValue(node,atomns,"content",null);}
+atomAttrib.content=value;}}
+this.parsePersonConstructs(node,"contributor",atomAttrib);atomAttrib.id=this.getFirstChildValue(node,atomns,"id",null);nodes=this.getElementsByTagNameNS(node,atomns,"link");if(nodes.length>0){atomAttrib.links=new Array(nodes.length);}
+var oAtts=["rel","type","hreflang","title","length"];for(var i=0,ii=nodes.length;i<ii;i++){value={};value.href=nodes[i].getAttribute("href");for(var j=0,jj=oAtts.length;j<jj;j++){attval=nodes[i].getAttribute(oAtts[j]);if(attval){value[oAtts[j]]=attval;}}
+atomAttrib.links[i]=value;}
+value=this.getFirstChildValue(node,atomns,"published",null);if(value){atomAttrib.published=value;}
+value=this.getFirstChildValue(node,atomns,"rights",null);if(value){atomAttrib.rights=value;}
+value=this.getFirstChildValue(node,atomns,"summary",null);if(value){atomAttrib.summary=value;}
+atomAttrib.title=this.getFirstChildValue(node,atomns,"title",null);atomAttrib.updated=this.getFirstChildValue(node,atomns,"updated",null);var featureAttrib={title:atomAttrib.title,description:atomAttrib.summary,atom:atomAttrib};var geometry=this.parseLocations(node)[0];var feature=new OpenLayers.Feature.Vector(geometry,featureAttrib);feature.fid=atomAttrib.id;return feature;},parseFeatures:function(node){var features=[];var entries=this.getElementsByTagNameNS(node,this.namespaces.atom,"entry");if(entries.length==0){entries=[node];}
+for(var i=0,ii=entries.length;i<ii;i++){features.push(this.parseFeature(entries[i]));}
+return features;},parseLocations:function(node){var georssns=this.namespaces.georss;var locations={components:[]};var where=this.getElementsByTagNameNS(node,georssns,"where");if(where&&where.length>0){if(!this.gmlParser){this.initGmlParser();}
+for(var i=0,ii=where.length;i<ii;i++){this.gmlParser.readChildNodes(where[i],locations);}}
+var components=locations.components;var point=this.getElementsByTagNameNS(node,georssns,"point");if(point&&point.length>0){for(var i=0,ii=point.length;i<ii;i++){var xy=OpenLayers.String.trim(point[i].firstChild.nodeValue).split(/\s+/);if(xy.length!=2){xy=OpenLayers.String.trim(point[i].firstChild.nodeValue).split(/\s*,\s*/);}
+components.push(new OpenLayers.Geometry.Point(parseFloat(xy[1]),parseFloat(xy[0])));}}
+var line=this.getElementsByTagNameNS(node,georssns,"line");if(line&&line.length>0){var coords;var p;var points;for(var i=0,ii=line.length;i<ii;i++){coords=OpenLayers.String.trim(line[i].firstChild.nodeValue).split(/\s+/);points=[];for(var j=0,jj=coords.length;j<jj;j+=2){p=new OpenLayers.Geometry.Point(parseFloat(coords[j+1]),parseFloat(coords[j]));points.push(p);}
+components.push(new OpenLayers.Geometry.LineString(points));}}
+var polygon=this.getElementsByTagNameNS(node,georssns,"polygon");if(polygon&&polygon.length>0){var coords;var p;var points;for(var i=0,ii=polygon.length;i<ii;i++){coords=OpenLayers.String.trim(polygon[i].firstChild.nodeValue).split(/\s+/);points=[];for(var j=0,jj=coords.length;j<jj;j+=2){p=new OpenLayers.Geometry.Point(parseFloat(coords[j+1]),parseFloat(coords[j]));points.push(p);}
+components.push(new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]));}}
+if(this.internalProjection&&this.externalProjection){for(var i=0,ii=components.length;i<ii;i++){if(components[i]){components[i].transform(this.externalProjection,this.internalProjection);}}}
+return components;},parsePersonConstructs:function(node,name,data){var persons=[];var atomns=this.namespaces.atom;var nodes=this.getElementsByTagNameNS(node,atomns,name);var oAtts=["uri","email"];for(var i=0,ii=nodes.length;i<ii;i++){var value={};value.name=this.getFirstChildValue(nodes[i],atomns,"name",null);for(var j=0,jj=oAtts.length;j<jj;j++){var attval=this.getFirstChildValue(nodes[i],atomns,oAtts[j],null);if(attval){value[oAtts[j]]=attval;}}
+persons.push(value);}
+if(persons.length>0){data[name+"s"]=persons;}},CLASS_NAME:"OpenLayers.Format.Atom"});OpenLayers.Format.Filter.v1_0_0=OpenLayers.Class(OpenLayers.Format.GML.v2,OpenLayers.Format.Filter.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/ogc/filter/1.0.0/filter.xsd",initialize:function(options){OpenLayers.Format.GML.v2.prototype.initialize.apply(this,[options]);},readers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsNotEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.NOT_EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLike":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LIKE});this.readChildNodes(node,filter);var wildCard=node.getAttribute("wildCard");var singleChar=node.getAttribute("singleChar");var esc=node.getAttribute("escape");filter.value2regex(wildCard,singleChar,esc);obj.filters.push(filter);}},OpenLayers.Format.Filter.v1.prototype.readers["ogc"]),"gml":OpenLayers.Format.GML.v2.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.readers["feature"]},writers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsNotEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsNotEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsLike":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLike",{attributes:{wildCard:"*",singleChar:".",escape:"!"}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.regex2value(),node);return node;},"BBOX":function(filter){var node=this.createElementNSPlus("ogc:BBOX");this.writeNode("PropertyName",filter,node);var box=this.writeNode("gml:Box",filter.value,node);if(filter.projection){box.setAttribute("srsName",filter.projection);}
+return node;}},OpenLayers.Format.Filter.v1.prototype.writers["ogc"]),"gml":OpenLayers.Format.GML.v2.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.writers["feature"]},writeSpatial:function(filter,name){var node=this.createElementNSPlus("ogc:"+name);this.writeNode("PropertyName",filter,node);var child;if(filter.value instanceof OpenLayers.Geometry){child=this.writeNode("feature:_geometry",filter.value).firstChild;}else{child=this.writeNode("gml:Box",filter.value);}
+if(filter.projection){child.setAttribute("srsName",filter.projection);}
+node.appendChild(child);return node;},CLASS_NAME:"OpenLayers.Format.Filter.v1_0_0"});OpenLayers.Format.Filter.v1_1_0=OpenLayers.Class(OpenLayers.Format.GML.v3,OpenLayers.Format.Filter.v1,{VERSION:"1.1.0",schemaLocation:"http://www.opengis.net/ogc/filter/1.1.0/filter.xsd",initialize:function(options){OpenLayers.Format.GML.v3.prototype.initialize.apply(this,[options]);},readers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(node,obj){var matchCase=node.getAttribute("matchCase");var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO,matchCase:!(matchCase==="false"||matchCase==="0")});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsNotEqualTo":function(node,obj){var matchCase=node.getAttribute("matchCase");var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.NOT_EQUAL_TO,matchCase:!(matchCase==="false"||matchCase==="0")});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLike":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LIKE});this.readChildNodes(node,filter);var wildCard=node.getAttribute("wildCard");var singleChar=node.getAttribute("singleChar");var esc=node.getAttribute("escapeChar");filter.value2regex(wildCard,singleChar,esc);obj.filters.push(filter);}},OpenLayers.Format.Filter.v1.prototype.readers["ogc"]),"gml":OpenLayers.Format.GML.v3.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.readers["feature"]},writers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsEqualTo",{attributes:{matchCase:filter.matchCase}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsNotEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsNotEqualTo",{attributes:{matchCase:filter.matchCase}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsLike":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLike",{attributes:{wildCard:"*",singleChar:".",escapeChar:"!"}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.regex2value(),node);return node;},"BBOX":function(filter){var node=this.createElementNSPlus("ogc:BBOX");this.writeNode("PropertyName",filter,node);var box=this.writeNode("gml:Envelope",filter.value);if(filter.projection){box.setAttribute("srsName",filter.projection);}
+node.appendChild(box);return node;}},OpenLayers.Format.Filter.v1.prototype.writers["ogc"]),"gml":OpenLayers.Format.GML.v3.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.writers["feature"]},writeSpatial:function(filter,name){var node=this.createElementNSPlus("ogc:"+name);this.writeNode("PropertyName",filter,node);var child;if(filter.value instanceof OpenLayers.Geometry){child=this.writeNode("feature:_geometry",filter.value).firstChild;}else{child=this.writeNode("gml:Envelope",filter.value);}
+if(filter.projection){child.setAttribute("srsName",filter.projection);}
+node.appendChild(child);return node;},CLASS_NAME:"OpenLayers.Format.Filter.v1_1_0"});OpenLayers.Format.SOSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.SOSCapabilities,{namespaces:{ows:"http://www.opengis.net/ows/1.1",sos:"http://www.opengis.net/sos/1.0",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink"},regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+if(data&&data.nodeType==9){data=data.documentElement;}
+var capabilities={};this.readNode(data,capabilities);return capabilities;},readers:{"gml":OpenLayers.Util.applyDefaults({"name":function(node,obj){obj.name=this.getChildValue(node);},"TimePeriod":function(node,obj){obj.timePeriod={};this.readChildNodes(node,obj.timePeriod);},"beginPosition":function(node,timePeriod){timePeriod.beginPosition=this.getChildValue(node);},"endPosition":function(node,timePeriod){timePeriod.endPosition=this.getChildValue(node);}},OpenLayers.Format.GML.v3.prototype.readers["gml"]),"sos":{"Capabilities":function(node,obj){this.readChildNodes(node,obj);},"Contents":function(node,obj){obj.contents={};this.readChildNodes(node,obj.contents);},"ObservationOfferingList":function(node,contents){contents.offeringList={};this.readChildNodes(node,contents.offeringList);},"ObservationOffering":function(node,offeringList){var id=this.getAttributeNS(node,this.namespaces.gml,"id");offeringList[id]={procedures:[],observedProperties:[],featureOfInterestIds:[],responseFormats:[],resultModels:[],responseModes:[]};this.readChildNodes(node,offeringList[id]);},"time":function(node,offering){offering.time={};this.readChildNodes(node,offering.time);},"procedure":function(node,offering){offering.procedures.push(this.getAttributeNS(node,this.namespaces.xlink,"href"));},"observedProperty":function(node,offering){offering.observedProperties.push(this.getAttributeNS(node,this.namespaces.xlink,"href"));},"featureOfInterest":function(node,offering){offering.featureOfInterestIds.push(this.getAttributeNS(node,this.namespaces.xlink,"href"));},"responseFormat":function(node,offering){offering.responseFormats.push(this.getChildValue(node));},"resultModel":function(node,offering){offering.resultModels.push(this.getChildValue(node));},"responseMode":function(node,offering){offering.responseModes.push(this.getChildValue(node));;}},"ows":OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers["ows"]},CLASS_NAME:"OpenLayers.Format.SOSCapabilities.v1_0_0"});OpenLayers.Format.SOSGetFeatureOfInterest=OpenLayers.Class(OpenLayers.Format.XML,{VERSION:"1.0.0",namespaces:{sos:"http://www.opengis.net/sos/1.0",gml:"http://www.opengis.net/gml",sa:"http://www.opengis.net/sampling/1.0",xsi:"http://www.w3.org/2001/XMLSchema-instance"},schemaLocation:"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosAll.xsd",defaultPrefix:"sos",regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+if(data&&data.nodeType==9){data=data.documentElement;}
+var info={features:[]};this.readNode(data,info);var features=[];for(var i=0,len=info.features.length;i<len;i++){var container=info.features[i];if(this.internalProjection&&this.externalProjection&&container.components[0]){container.components[0].transform(this.externalProjection,this.internalProjection);}
+var feature=new OpenLayers.Feature.Vector(container.components[0],container.attributes);features.push(feature);}
+return features;},readers:{"sa":{"SamplingPoint":function(node,obj){if(!obj.attributes){var feature={attributes:{}};obj.features.push(feature);obj=feature;}
+obj.attributes.id=this.getAttributeNS(node,this.namespaces.gml,"id");this.readChildNodes(node,obj);},"position":function(node,obj){this.readChildNodes(node,obj);}},"gml":OpenLayers.Util.applyDefaults({"FeatureCollection":function(node,obj){this.readChildNodes(node,obj);},"featureMember":function(node,obj){var feature={attributes:{}};obj.features.push(feature);this.readChildNodes(node,feature);},"name":function(node,obj){obj.attributes.name=this.getChildValue(node);},"pos":function(node,obj){if(!this.externalProjection){this.externalProjection=new OpenLayers.Projection(node.getAttribute("srsName"));}
+OpenLayers.Format.GML.v3.prototype.readers.gml.pos.apply(this,[node,obj]);}},OpenLayers.Format.GML.v3.prototype.readers.gml)},writers:{"sos":{"GetFeatureOfInterest":function(options){var node=this.createElementNSPlus("GetFeatureOfInterest",{attributes:{version:this.VERSION,service:'SOS',"xsi:schemaLocation":this.schemaLocation}});for(var i=0,len=options.fois.length;i<len;i++){this.writeNode("FeatureOfInterestId",{foi:options.fois[i]},node);}
+return node;},"FeatureOfInterestId":function(options){var node=this.createElementNSPlus("FeatureOfInterestId",{value:options.foi});return node;}}},CLASS_NAME:"OpenLayers.Format.SOSGetFeatureOfInterest"});OpenLayers.Format.SOSGetObservation=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ows:"http://www.opengis.net/ows",gml:"http://www.opengis.net/gml",sos:"http://www.opengis.net/sos/1.0",ogc:"http://www.opengis.net/ogc",om:"http://www.opengis.net/om/1.0",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd",defaultPrefix:"sos",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+if(data&&data.nodeType==9){data=data.documentElement;}
+var info={measurements:[]};this.readNode(data,info);return info;},write:function(options){var node=this.writeNode("sos:GetObservation",options);node.setAttribute("xmlns:om",this.namespaces.om);this.setAttributeNS(node,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},readers:{"om":{"ObservationCollection":function(node,obj){obj.id=this.getAttributeNS(node,this.namespaces.gml,"id");this.readChildNodes(node,obj);},"member":function(node,observationCollection){this.readChildNodes(node,observationCollection);},"Measurement":function(node,observationCollection){var measurement={};observationCollection.measurements.push(measurement);this.readChildNodes(node,measurement);},"samplingTime":function(node,measurement){var samplingTime={};measurement.samplingTime=samplingTime;this.readChildNodes(node,samplingTime);},"observedProperty":function(node,measurement){measurement.observedProperty=this.getAttributeNS(node,this.namespaces.xlink,"href");this.readChildNodes(node,measurement);},"procedure":function(node,measurement){measurement.procedure=this.getAttributeNS(node,this.namespaces.xlink,"href");this.readChildNodes(node,measurement);},"result":function(node,measurement){var result={};measurement.result=result;if(this.getChildValue(node)!==''){result.value=this.getChildValue(node);result.uom=node.getAttribute("uom");}else{this.readChildNodes(node,result);}}},"gml":OpenLayers.Util.applyDefaults({"TimeInstant":function(node,samplingTime){var timeInstant={};samplingTime.timeInstant=timeInstant;this.readChildNodes(node,timeInstant);},"timePosition":function(node,timeInstant){timeInstant.timePosition=this.getChildValue(node);}},OpenLayers.Format.GML.v3.prototype.readers.gml)},writers:{"sos":{"GetObservation":function(options){var node=this.createElementNSPlus("GetObservation",{attributes:{version:this.VERSION,service:'SOS'}});this.writeNode("offering",options,node);this.writeNode("eventTime",options,node);this.writeNode("procedure",options,node);this.writeNode("observedProperty",options,node);this.writeNode("responseFormat",options,node);this.writeNode("resultModel",options,node);this.writeNode("responseMode",options,node);return node;},"responseFormat":function(options){return this.createElementNSPlus("responseFormat",{value:options.responseFormat});},"procedure":function(options){return this.createElementNSPlus("procedure",{value:options.procedure});},"offering":function(options){return this.createElementNSPlus("offering",{value:options.offering});},"observedProperty":function(options){return this.createElementNSPlus("observedProperty",{value:options.observedProperty});},"eventTime":function(options){var node=this.createElementNSPlus("eventTime");if(options.eventTime==='latest'){this.writeNode("ogc:TM_Equals",options,node);}
+return node;},"resultModel":function(options){return this.createElementNSPlus("resultModel",{value:options.resultModel});},"responseMode":function(options){return this.createElementNSPlus("responseMode",{value:options.responseMode});}},"ogc":{"TM_Equals":function(options){var node=this.createElementNSPlus("ogc:TM_Equals");this.writeNode("ogc:PropertyName",{property:"urn:ogc:data:time:iso8601"},node);if(options.eventTime==='latest'){this.writeNode("gml:TimeInstant",{value:'latest'},node);}
+return node;},"PropertyName":function(options){return this.createElementNSPlus("ogc:PropertyName",{value:options.property});}},"gml":{"TimeInstant":function(options){var node=this.createElementNSPlus("gml:TimeInstant");this.writeNode("gml:timePosition",options,node);return node;},"timePosition":function(options){var node=this.createElementNSPlus("gml:timePosition",{value:options.value});return node;}}},CLASS_NAME:"OpenLayers.Format.SOSGetObservation"});OpenLayers.Format.CSWGetRecords.v2_0_2=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",csw:"http://www.opengis.net/cat/csw/2.0.2",dc:"http://purl.org/dc/elements/1.1/",dct:"http://purl.org/dc/terms/",ows:"http://www.opengis.net/ows"},defaultPrefix:"csw",version:"2.0.2",schemaLocation:"http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd",requestId:null,resultType:null,outputFormat:null,outputSchema:null,startPosition:null,maxRecords:null,DistributedSearch:null,ResponseHandler:null,Query:null,regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+if(data&&data.nodeType==9){data=data.documentElement;}
+var obj={};this.readNode(data,obj);return obj;},readers:{"csw":{"GetRecordsResponse":function(node,obj){obj.records=[];this.readChildNodes(node,obj);var version=this.getAttributeNS(node,"",'version');if(version!=""){obj.version=version;}},"RequestId":function(node,obj){obj.RequestId=this.getChildValue(node);},"SearchStatus":function(node,obj){obj.SearchStatus={};var timestamp=this.getAttributeNS(node,"",'timestamp');if(timestamp!=""){obj.SearchStatus.timestamp=timestamp;}},"SearchResults":function(node,obj){this.readChildNodes(node,obj);var attrs=node.attributes;var SearchResults={};for(var i=0,len=attrs.length;i<len;++i){if((attrs[i].name=="numberOfRecordsMatched")||(attrs[i].name=="numberOfRecordsReturned")||(attrs[i].name=="nextRecord")){SearchResults[attrs[i].name]=parseInt(attrs[i].nodeValue);}else{SearchResults[attrs[i].name]=attrs[i].nodeValue;}}
+obj.SearchResults=SearchResults;},"SummaryRecord":function(node,obj){var record={type:"SummaryRecord"};this.readChildNodes(node,record);obj.records.push(record);},"BriefRecord":function(node,obj){var record={type:"BriefRecord"};this.readChildNodes(node,record);obj.records.push(record);},"DCMIRecord":function(node,obj){var record={type:"DCMIRecord"};this.readChildNodes(node,record);obj.records.push(record);},"Record":function(node,obj){var record={type:"Record"};this.readChildNodes(node,record);obj.records.push(record);}},"dc":{"*":function(node,obj){var name=node.localName||node.nodeName.split(":").pop();if(!(obj[name]instanceof Array)){obj[name]=new Array();}
+var dc_element={};var attrs=node.attributes;for(var i=0,len=attrs.length;i<len;++i){dc_element[attrs[i].name]=attrs[i].nodeValue;}
+dc_element.value=this.getChildValue(node);obj[name].push(dc_element);}},"dct":{"*":function(node,obj){var name=node.localName||node.nodeName.split(":").pop();if(!(obj[name]instanceof Array)){obj[name]=new Array();}
+obj[name].push(this.getChildValue(node));}},"ows":OpenLayers.Util.applyDefaults({"BoundingBox":function(node,obj){if(obj.bounds){obj.BoundingBox=[{crs:obj.projection,value:[obj.bounds.left,obj.bounds.bottom,obj.bounds.right,obj.bounds.top]}];delete obj.projection;delete obj.bounds;}
+OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers["ows"]["BoundingBox"].apply(this,arguments);}},OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers["ows"])},write:function(options){var node=this.writeNode("csw:GetRecords",options);return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},writers:{"csw":{"GetRecords":function(options){if(!options){options={};}
+var node=this.createElementNSPlus("csw:GetRecords",{attributes:{service:"CSW",version:this.version,requestId:options.requestId||this.requestId,resultType:options.resultType||this.resultType,outputFormat:options.outputFormat||this.outputFormat,outputSchema:options.outputSchema||this.outputSchema,startPosition:options.startPosition||this.startPosition,maxRecords:options.maxRecords||this.maxRecords}});if(options.DistributedSearch||this.DistributedSearch){this.writeNode("csw:DistributedSearch",options.DistributedSearch||this.DistributedSearch,node);}
+var ResponseHandler=options.ResponseHandler||this.ResponseHandler;if(ResponseHandler instanceof Array&&ResponseHandler.length>0){for(var i=0,len=ResponseHandler.length;i<len;i++){this.writeNode("csw:ResponseHandler",ResponseHandler[i],node);}}
+this.writeNode("Query",options.Query||this.Query,node);return node;},"DistributedSearch":function(options){var node=this.createElementNSPlus("csw:DistributedSearch",{attributes:{hopCount:options.hopCount}});return node;},"ResponseHandler":function(options){var node=this.createElementNSPlus("csw:ResponseHandler",{value:options.value});return node;},"Query":function(options){if(!options){options={};}
+var node=this.createElementNSPlus("csw:Query",{attributes:{typeNames:options.typeNames||"csw:Record"}});var ElementName=options.ElementName;if(ElementName instanceof Array&&ElementName.length>0){for(var i=0,len=ElementName.length;i<len;i++){this.writeNode("csw:ElementName",ElementName[i],node);}}else{this.writeNode("csw:ElementSetName",options.ElementSetName||{value:'summary'},node);}
+if(options.Constraint){this.writeNode("csw:Constraint",options.Constraint,node);}
+return node;},"ElementName":function(options){var node=this.createElementNSPlus("csw:ElementName",{value:options.value});return node;},"ElementSetName":function(options){var node=this.createElementNSPlus("csw:ElementSetName",{attributes:{typeNames:options.typeNames},value:options.value});return node;},"Constraint":function(options){var node=this.createElementNSPlus("csw:Constraint",{attributes:{version:options.version}});if(options.Filter){var format=new OpenLayers.Format.Filter({version:options.version});node.appendChild(format.write(options.Filter));}else if(options.CqlText){var child=this.createElementNSPlus("CqlText",{value:options.CqlText.value});node.appendChild(child);}
+return node;}}},CLASS_NAME:"OpenLayers.Format.CSWGetRecords.v2_0_2"});OpenLayers.Format.SLD.v1=OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0,{namespaces:{sld:"http://www.opengis.net/sld",ogc:"http://www.opengis.net/ogc",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"sld",schemaLocation:null,multipleSymbolizers:false,featureTypeCounter:null,defaultSymbolizer:{fillColor:"#808080",fillOpacity:1,strokeColor:"#000000",strokeOpacity:1,strokeWidth:1,strokeDashstyle:"solid",pointRadius:3,graphicName:"square"},initialize:function(options){OpenLayers.Format.Filter.v1_0_0.prototype.initialize.apply(this,[options]);},read:function(data,options){options=OpenLayers.Util.applyDefaults(options,this.options);var sld={namedLayers:options.namedLayersAsArray===true?[]:{}};this.readChildNodes(data,sld);return sld;},readers:OpenLayers.Util.applyDefaults({"sld":{"StyledLayerDescriptor":function(node,sld){sld.version=node.getAttribute("version");this.readChildNodes(node,sld);},"Name":function(node,obj){obj.name=this.getChildValue(node);},"Title":function(node,obj){obj.title=this.getChildValue(node);},"Abstract":function(node,obj){obj.description=this.getChildValue(node);},"NamedLayer":function(node,sld){var layer={userStyles:[],namedStyles:[]};this.readChildNodes(node,layer);for(var i=0,len=layer.userStyles.length;i<len;++i){layer.userStyles[i].layerName=layer.name;}
+if(sld.namedLayers instanceof Array){sld.namedLayers.push(layer);}else{sld.namedLayers[layer.name]=layer;}},"NamedStyle":function(node,layer){layer.namedStyles.push(this.getChildName(node.firstChild));},"UserStyle":function(node,layer){var obj={defaultsPerSymbolizer:true,rules:[]};this.featureTypeCounter=-1;this.readChildNodes(node,obj);var style;if(this.multipleSymbolizers){delete obj.defaultsPerSymbolizer;style=new OpenLayers.Style2(obj);}else{style=new OpenLayers.Style(this.defaultSymbolizer,obj);}
+layer.userStyles.push(style);},"IsDefault":function(node,style){if(this.getChildValue(node)=="1"){style.isDefault=true;}},"FeatureTypeStyle":function(node,style){++this.featureTypeCounter;var obj={rules:this.multipleSymbolizers?style.rules:[]};this.readChildNodes(node,obj);if(!this.multipleSymbolizers){style.rules=obj.rules;}},"Rule":function(node,obj){var config;if(this.multipleSymbolizers){config={symbolizers:[]};}
+var rule=new OpenLayers.Rule(config);this.readChildNodes(node,rule);obj.rules.push(rule);},"ElseFilter":function(node,rule){rule.elseFilter=true;},"MinScaleDenominator":function(node,rule){rule.minScaleDenominator=parseFloat(this.getChildValue(node));},"MaxScaleDenominator":function(node,rule){rule.maxScaleDenominator=parseFloat(this.getChildValue(node));},"TextSymbolizer":function(node,rule){var config={};this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Text(config));}else{rule.symbolizer["Text"]=OpenLayers.Util.applyDefaults(config,rule.symbolizer["Text"]);}},"Label":function(node,symbolizer){var obj={};this.readChildNodes(node,obj);if(obj.property){symbolizer.label="${"+obj.property+"}";}else{var value=this.readOgcExpression(node);if(value){symbolizer.label=value;}}},"Font":function(node,symbolizer){this.readChildNodes(node,symbolizer);},"Halo":function(node,symbolizer){var obj={};this.readChildNodes(node,obj);symbolizer.haloRadius=obj.haloRadius;symbolizer.haloColor=obj.fillColor;symbolizer.haloOpacity=obj.fillOpacity;},"Radius":function(node,symbolizer){var radius=this.readOgcExpression(node);if(radius!=null){symbolizer.haloRadius=radius;}},"RasterSymbolizer":function(node,rule){var config={};this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Raster(config));}else{rule.symbolizer["Raster"]=OpenLayers.Util.applyDefaults(config,rule.symbolizer["Raster"]);}},"Geometry":function(node,obj){obj.geometry={};this.readChildNodes(node,obj.geometry);},"ColorMap":function(node,symbolizer){symbolizer.colorMap=[];this.readChildNodes(node,symbolizer.colorMap);},"ColorMapEntry":function(node,colorMap){var q=node.getAttribute("quantity");var o=node.getAttribute("opacity");colorMap.push({color:node.getAttribute("color"),quantity:q!==null?parseFloat(q):undefined,label:node.getAttribute("label")||undefined,opacity:o!==null?parseFloat(o):undefined});},"LineSymbolizer":function(node,rule){var config={};this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Line(config));}else{rule.symbolizer["Line"]=OpenLayers.Util.applyDefaults(config,rule.symbolizer["Line"]);}},"PolygonSymbolizer":function(node,rule){var config={fill:false,stroke:false};if(!this.multipleSymbolizers){config=rule.symbolizer["Polygon"]||config;}
+this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Polygon(config));}else{rule.symbolizer["Polygon"]=config;}},"PointSymbolizer":function(node,rule){var config={fill:false,stroke:false,graphic:false};if(!this.multipleSymbolizers){config=rule.symbolizer["Point"]||config;}
+this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Point(config));}else{rule.symbolizer["Point"]=config;}},"Stroke":function(node,symbolizer){symbolizer.stroke=true;this.readChildNodes(node,symbolizer);},"Fill":function(node,symbolizer){symbolizer.fill=true;this.readChildNodes(node,symbolizer);},"CssParameter":function(node,symbolizer){var cssProperty=node.getAttribute("name");var symProperty=this.cssMap[cssProperty];if(symProperty){var value=this.readOgcExpression(node);if(value){symbolizer[symProperty]=value;}}},"Graphic":function(node,symbolizer){symbolizer.graphic=true;var graphic={};this.readChildNodes(node,graphic);var properties=["stroke","strokeColor","strokeWidth","strokeOpacity","strokeLinecap","fill","fillColor","fillOpacity","graphicName","rotation","graphicFormat"];var prop,value;for(var i=0,len=properties.length;i<len;++i){prop=properties[i];value=graphic[prop];if(value!=undefined){symbolizer[prop]=value;}}
+if(graphic.opacity!=undefined){symbolizer.graphicOpacity=graphic.opacity;}
+if(graphic.size!=undefined){symbolizer.pointRadius=graphic.size/2;}
+if(graphic.href!=undefined){symbolizer.externalGraphic=graphic.href;}
+if(graphic.rotation!=undefined){symbolizer.rotation=graphic.rotation;}},"ExternalGraphic":function(node,graphic){this.readChildNodes(node,graphic);},"Mark":function(node,graphic){this.readChildNodes(node,graphic);},"WellKnownName":function(node,graphic){graphic.graphicName=this.getChildValue(node);},"Opacity":function(node,obj){var opacity=this.readOgcExpression(node);if(opacity){obj.opacity=opacity;}},"Size":function(node,obj){var size=this.readOgcExpression(node);if(size){obj.size=size;}},"Rotation":function(node,obj){var rotation=this.readOgcExpression(node);if(rotation){obj.rotation=rotation;}},"OnlineResource":function(node,obj){obj.href=this.getAttributeNS(node,this.namespaces.xlink,"href");},"Format":function(node,graphic){graphic.graphicFormat=this.getChildValue(node);}}},OpenLayers.Format.Filter.v1_0_0.prototype.readers),cssMap:{"stroke":"strokeColor","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","stroke-linecap":"strokeLinecap","stroke-dasharray":"strokeDashstyle","fill":"fillColor","fill-opacity":"fillOpacity","font-family":"fontFamily","font-size":"fontSize","font-weight":"fontWeight","font-style":"fontStyle"},getCssProperty:function(sym){var css=null;for(var prop in this.cssMap){if(this.cssMap[prop]==sym){css=prop;break;}}
+return css;},getGraphicFormat:function(href){var format,regex;for(var key in this.graphicFormats){if(this.graphicFormats[key].test(href)){format=key;break;}}
+return format||this.defautlGraphicFormat;},defaultGraphicFormat:"image/png",graphicFormats:{"image/jpeg":/\.jpe?g$/i,"image/gif":/\.gif$/i,"image/png":/\.png$/i},write:function(sld){return this.writers.sld.StyledLayerDescriptor.apply(this,[sld]);},writers:OpenLayers.Util.applyDefaults({"sld":{"StyledLayerDescriptor":function(sld){var root=this.createElementNSPlus("sld:StyledLayerDescriptor",{attributes:{"version":this.VERSION,"xsi:schemaLocation":this.schemaLocation}});root.setAttribute("xmlns:ogc",this.namespaces.ogc);root.setAttribute("xmlns:gml",this.namespaces.gml);if(sld.name){this.writeNode("Name",sld.name,root);}
+if(sld.title){this.writeNode("Title",sld.title,root);}
+if(sld.description){this.writeNode("Abstract",sld.description,root);}
+if(sld.namedLayers instanceof Array){for(var i=0,len=sld.namedLayers.length;i<len;++i){this.writeNode("NamedLayer",sld.namedLayers[i],root);}}else{for(var name in sld.namedLayers){this.writeNode("NamedLayer",sld.namedLayers[name],root);}}
+return root;},"Name":function(name){return this.createElementNSPlus("sld:Name",{value:name});},"Title":function(title){return this.createElementNSPlus("sld:Title",{value:title});},"Abstract":function(description){return this.createElementNSPlus("sld:Abstract",{value:description});},"NamedLayer":function(layer){var node=this.createElementNSPlus("sld:NamedLayer");this.writeNode("Name",layer.name,node);if(layer.namedStyles){for(var i=0,len=layer.namedStyles.length;i<len;++i){this.writeNode("NamedStyle",layer.namedStyles[i],node);}}
+if(layer.userStyles){for(var i=0,len=layer.userStyles.length;i<len;++i){this.writeNode("UserStyle",layer.userStyles[i],node);}}
+return node;},"NamedStyle":function(name){var node=this.createElementNSPlus("sld:NamedStyle");this.writeNode("Name",name,node);return node;},"UserStyle":function(style){var node=this.createElementNSPlus("sld:UserStyle");if(style.name){this.writeNode("Name",style.name,node);}
+if(style.title){this.writeNode("Title",style.title,node);}
+if(style.description){this.writeNode("Abstract",style.description,node);}
+if(style.isDefault){this.writeNode("IsDefault",style.isDefault,node);}
+if(this.multipleSymbolizers&&style.rules){var rulesByZ={0:[]};var zValues=[0];var rule,ruleMap,symbolizer,zIndex,clone;for(var i=0,ii=style.rules.length;i<ii;++i){rule=style.rules[i];if(rule.symbolizers){ruleMap={};for(var j=0,jj=rule.symbolizers.length;j<jj;++j){symbolizer=rule.symbolizers[j];zIndex=symbolizer.zIndex;if(!(zIndex in ruleMap)){clone=rule.clone();clone.symbolizers=[];ruleMap[zIndex]=clone;}
+ruleMap[zIndex].symbolizers.push(symbolizer.clone());}
+for(zIndex in ruleMap){if(!(zIndex in rulesByZ)){zValues.push(zIndex);rulesByZ[zIndex]=[];}
+rulesByZ[zIndex].push(ruleMap[zIndex]);}}else{rulesByZ[0].push(rule.clone());}}
+zValues.sort();var rules;for(var i=0,ii=zValues.length;i<ii;++i){rules=rulesByZ[zValues[i]];if(rules.length>0){clone=style.clone();clone.rules=rulesByZ[zValues[i]];this.writeNode("FeatureTypeStyle",clone,node);}}}else{this.writeNode("FeatureTypeStyle",style,node);}
+return node;},"IsDefault":function(bool){return this.createElementNSPlus("sld:IsDefault",{value:(bool)?"1":"0"});},"FeatureTypeStyle":function(style){var node=this.createElementNSPlus("sld:FeatureTypeStyle");for(var i=0,len=style.rules.length;i<len;++i){this.writeNode("Rule",style.rules[i],node);}
+return node;},"Rule":function(rule){var node=this.createElementNSPlus("sld:Rule");if(rule.name){this.writeNode("Name",rule.name,node);}
+if(rule.title){this.writeNode("Title",rule.title,node);}
+if(rule.description){this.writeNode("Abstract",rule.description,node);}
+if(rule.elseFilter){this.writeNode("ElseFilter",null,node);}else if(rule.filter){this.writeNode("ogc:Filter",rule.filter,node);}
+if(rule.minScaleDenominator!=undefined){this.writeNode("MinScaleDenominator",rule.minScaleDenominator,node);}
+if(rule.maxScaleDenominator!=undefined){this.writeNode("MaxScaleDenominator",rule.maxScaleDenominator,node);}
+var type,symbolizer;if(this.multipleSymbolizers&&rule.symbolizers){var symbolizer;for(var i=0,ii=rule.symbolizers.length;i<ii;++i){symbolizer=rule.symbolizers[i];type=symbolizer.CLASS_NAME.split(".").pop();this.writeNode(type+"Symbolizer",symbolizer,node);}}else{var types=OpenLayers.Style.SYMBOLIZER_PREFIXES;for(var i=0,len=types.length;i<len;++i){type=types[i];symbolizer=rule.symbolizer[type];if(symbolizer){this.writeNode(type+"Symbolizer",symbolizer,node);}}}
+return node;},"ElseFilter":function(){return this.createElementNSPlus("sld:ElseFilter");},"MinScaleDenominator":function(scale){return this.createElementNSPlus("sld:MinScaleDenominator",{value:scale});},"MaxScaleDenominator":function(scale){return this.createElementNSPlus("sld:MaxScaleDenominator",{value:scale});},"LineSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:LineSymbolizer");this.writeNode("Stroke",symbolizer,node);return node;},"Stroke":function(symbolizer){var node=this.createElementNSPlus("sld:Stroke");if(symbolizer.strokeColor!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeColor"},node);}
+if(symbolizer.strokeOpacity!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeOpacity"},node);}
+if(symbolizer.strokeWidth!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeWidth"},node);}
+if(symbolizer.strokeDashstyle!=undefined&&symbolizer.strokeDashstyle!=="solid"){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeDashstyle"},node);}
+if(symbolizer.strokeLinecap!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeLinecap"},node);}
+return node;},"CssParameter":function(obj){return this.createElementNSPlus("sld:CssParameter",{attributes:{name:this.getCssProperty(obj.key)},value:obj.symbolizer[obj.key]});},"TextSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:TextSymbolizer");if(symbolizer.label!=null){this.writeNode("Label",symbolizer.label,node);}
+if(symbolizer.fontFamily!=null||symbolizer.fontSize!=null||symbolizer.fontWeight!=null||symbolizer.fontStyle!=null){this.writeNode("Font",symbolizer,node);}
+if(symbolizer.haloRadius!=null||symbolizer.haloColor!=null||symbolizer.haloOpacity!=null){this.writeNode("Halo",symbolizer,node);}
+if(symbolizer.fillColor!=null||symbolizer.fillOpacity!=null){this.writeNode("Fill",symbolizer,node);}
+return node;},"Font":function(symbolizer){var node=this.createElementNSPlus("sld:Font");if(symbolizer.fontFamily){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontFamily"},node);}
+if(symbolizer.fontSize){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontSize"},node);}
+if(symbolizer.fontWeight){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontWeight"},node);}
+if(symbolizer.fontStyle){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontStyle"},node);}
+return node;},"Label":function(label){var node=this.createElementNSPlus("sld:Label");var tokens=label.split("${");node.appendChild(this.createTextNode(tokens[0]));var item,last;for(var i=1,len=tokens.length;i<len;i++){item=tokens[i];last=item.indexOf("}");if(last>0){this.writeNode("ogc:PropertyName",{property:item.substring(0,last)},node);node.appendChild(this.createTextNode(item.substring(++last)));}else{node.appendChild(this.createTextNode("${"+item));}}
+return node;},"Halo":function(symbolizer){var node=this.createElementNSPlus("sld:Halo");if(symbolizer.haloRadius){this.writeNode("Radius",symbolizer.haloRadius,node);}
+if(symbolizer.haloColor||symbolizer.haloOpacity){this.writeNode("Fill",{fillColor:symbolizer.haloColor,fillOpacity:symbolizer.haloOpacity},node);}
+return node;},"Radius":function(value){return this.createElementNSPlus("sld:Radius",{value:value});},"RasterSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:RasterSymbolizer");if(symbolizer.geometry){this.writeNode("Geometry",symbolizer.geometry,node);}
+if(symbolizer.opacity){this.writeNode("Opacity",symbolizer.opacity,node);}
+if(symbolizer.colorMap){this.writeNode("ColorMap",symbolizer.colorMap,node);}
+return node;},"Geometry":function(geometry){var node=this.createElementNSPlus("sld:Geometry");if(geometry.property){this.writeNode("ogc:PropertyName",geometry,node);}
+return node;},"ColorMap":function(colorMap){var node=this.createElementNSPlus("sld:ColorMap");for(var i=0,len=colorMap.length;i<len;++i){this.writeNode("ColorMapEntry",colorMap[i],node);}
+return node;},"ColorMapEntry":function(colorMapEntry){var node=this.createElementNSPlus("sld:ColorMapEntry");var a=colorMapEntry;node.setAttribute("color",a.color);a.opacity!==undefined&&node.setAttribute("opacity",parseFloat(a.opacity));a.quantity!==undefined&&node.setAttribute("quantity",parseFloat(a.quantity));a.label!==undefined&&node.setAttribute("label",a.label);return node;},"PolygonSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:PolygonSymbolizer");if(symbolizer.fill!==false){this.writeNode("Fill",symbolizer,node);}
+if(symbolizer.stroke!==false){this.writeNode("Stroke",symbolizer,node);}
+return node;},"Fill":function(symbolizer){var node=this.createElementNSPlus("sld:Fill");if(symbolizer.fillColor){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fillColor"},node);}
+if(symbolizer.fillOpacity!=null){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fillOpacity"},node);}
+return node;},"PointSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:PointSymbolizer");this.writeNode("Graphic",symbolizer,node);return node;},"Graphic":function(symbolizer){var node=this.createElementNSPlus("sld:Graphic");if(symbolizer.externalGraphic!=undefined){this.writeNode("ExternalGraphic",symbolizer,node);}else{this.writeNode("Mark",symbolizer,node);}
+if(symbolizer.graphicOpacity!=undefined){this.writeNode("Opacity",symbolizer.graphicOpacity,node);}
+if(symbolizer.pointRadius!=undefined){this.writeNode("Size",symbolizer.pointRadius*2,node);}
+if(symbolizer.rotation!=undefined){this.writeNode("Rotation",symbolizer.rotation,node);}
+return node;},"ExternalGraphic":function(symbolizer){var node=this.createElementNSPlus("sld:ExternalGraphic");this.writeNode("OnlineResource",symbolizer.externalGraphic,node);var format=symbolizer.graphicFormat||this.getGraphicFormat(symbolizer.externalGraphic);this.writeNode("Format",format,node);return node;},"Mark":function(symbolizer){var node=this.createElementNSPlus("sld:Mark");if(symbolizer.graphicName){this.writeNode("WellKnownName",symbolizer.graphicName,node);}
+if(symbolizer.fill!==false){this.writeNode("Fill",symbolizer,node);}
+if(symbolizer.stroke!==false){this.writeNode("Stroke",symbolizer,node);}
+return node;},"WellKnownName":function(name){return this.createElementNSPlus("sld:WellKnownName",{value:name});},"Opacity":function(value){return this.createElementNSPlus("sld:Opacity",{value:value});},"Size":function(value){return this.createElementNSPlus("sld:Size",{value:value});},"Rotation":function(value){return this.createElementNSPlus("sld:Rotation",{value:value});},"OnlineResource":function(href){return this.createElementNSPlus("sld:OnlineResource",{attributes:{"xlink:type":"simple","xlink:href":href}});},"Format":function(format){return this.createElementNSPlus("sld:Format",{value:format});}}},OpenLayers.Format.Filter.v1_0_0.prototype.writers),CLASS_NAME:"OpenLayers.Format.SLD.v1"});OpenLayers.Format.WFST.v1_0_0=OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0,OpenLayers.Format.WFST.v1,{version:"1.0.0",srsNameInQuery:false,schemaLocations:{"wfs":"http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd"},initialize:function(options){OpenLayers.Format.Filter.v1_0_0.prototype.initialize.apply(this,[options]);OpenLayers.Format.WFST.v1.prototype.initialize.apply(this,[options]);},readers:{"wfs":OpenLayers.Util.applyDefaults({"WFS_TransactionResponse":function(node,obj){obj.insertIds=[];obj.success=false;this.readChildNodes(node,obj);},"InsertResult":function(node,container){var obj={fids:[]};this.readChildNodes(node,obj);container.insertIds.push(obj.fids[0]);},"TransactionResult":function(node,obj){this.readChildNodes(node,obj);},"Status":function(node,obj){this.readChildNodes(node,obj);},"SUCCESS":function(node,obj){obj.success=true;}},OpenLayers.Format.WFST.v1.prototype.readers["wfs"]),"gml":OpenLayers.Format.GML.v2.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.readers["feature"],"ogc":OpenLayers.Format.Filter.v1_0_0.prototype.readers["ogc"]},writers:{"wfs":OpenLayers.Util.applyDefaults({"Query":function(options){options=OpenLayers.Util.extend({featureNS:this.featureNS,featurePrefix:this.featurePrefix,featureType:this.featureType,srsName:this.srsName,srsNameInQuery:this.srsNameInQuery},options);var node=this.createElementNSPlus("wfs:Query",{attributes:{typeName:(options.featureNS?options.featurePrefix+":":"")+
+options.featureType}});if(options.srsNameInQuery&&options.srsName){node.setAttribute("srsName",options.srsName);}
+if(options.featureNS){node.setAttribute("xmlns:"+options.featurePrefix,options.featureNS);}
+if(options.propertyNames){for(var i=0,len=options.propertyNames.length;i<len;i++){this.writeNode("ogc:PropertyName",{property:options.propertyNames[i]},node);}}
+if(options.filter){this.setFilterProperty(options.filter);this.writeNode("ogc:Filter",options.filter,node);}
+return node;}},OpenLayers.Format.WFST.v1.prototype.writers["wfs"]),"gml":OpenLayers.Format.GML.v2.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.writers["feature"],"ogc":OpenLayers.Format.Filter.v1_0_0.prototype.writers["ogc"]},CLASS_NAME:"OpenLayers.Format.WFST.v1_0_0"});OpenLayers.Format.WFST.v1_1_0=OpenLayers.Class(OpenLayers.Format.Filter.v1_1_0,OpenLayers.Format.WFST.v1,{version:"1.1.0",schemaLocations:{"wfs":"http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"},initialize:function(options){OpenLayers.Format.Filter.v1_1_0.prototype.initialize.apply(this,[options]);OpenLayers.Format.WFST.v1.prototype.initialize.apply(this,[options]);},readers:{"wfs":OpenLayers.Util.applyDefaults({"FeatureCollection":function(node,obj){obj.numberOfFeatures=parseInt(node.getAttribute("numberOfFeatures"));OpenLayers.Format.WFST.v1.prototype.readers["wfs"]["FeatureCollection"].apply(this,arguments);},"TransactionResponse":function(node,obj){obj.insertIds=[];obj.success=false;this.readChildNodes(node,obj);},"TransactionSummary":function(node,obj){obj.success=true;},"InsertResults":function(node,obj){this.readChildNodes(node,obj);},"Feature":function(node,container){var obj={fids:[]};this.readChildNodes(node,obj);container.insertIds.push(obj.fids[0]);}},OpenLayers.Format.WFST.v1.prototype.readers["wfs"]),"gml":OpenLayers.Format.GML.v3.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.readers["feature"],"ogc":OpenLayers.Format.Filter.v1_1_0.prototype.readers["ogc"]},writers:{"wfs":OpenLayers.Util.applyDefaults({"GetFeature":function(options){var node=OpenLayers.Format.WFST.v1.prototype.writers["wfs"]["GetFeature"].apply(this,arguments);options&&options.resultType&&this.setAttributes(node,{resultType:options.resultType});return node;},"Query":function(options){options=OpenLayers.Util.extend({featureNS:this.featureNS,featurePrefix:this.featurePrefix,featureType:this.featureType,srsName:this.srsName},options);var node=this.createElementNSPlus("wfs:Query",{attributes:{typeName:(options.featureNS?options.featurePrefix+":":"")+
+options.featureType,srsName:options.srsName}});if(options.featureNS){node.setAttribute("xmlns:"+options.featurePrefix,options.featureNS);}
+if(options.propertyNames){for(var i=0,len=options.propertyNames.length;i<len;i++){this.writeNode("wfs:PropertyName",{property:options.propertyNames[i]},node);}}
+if(options.filter){this.setFilterProperty(options.filter);this.writeNode("ogc:Filter",options.filter,node);}
+return node;},"PropertyName":function(obj){return this.createElementNSPlus("wfs:PropertyName",{value:obj.property});}},OpenLayers.Format.WFST.v1.prototype.writers["wfs"]),"gml":OpenLayers.Format.GML.v3.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.writers["feature"],"ogc":OpenLayers.Format.Filter.v1_1_0.prototype.writers["ogc"]},CLASS_NAME:"OpenLayers.Format.WFST.v1_1_0"});OpenLayers.Protocol.SOS.v1_0_0=OpenLayers.Class(OpenLayers.Protocol,{fois:null,formatOptions:null,initialize:function(options){OpenLayers.Protocol.prototype.initialize.apply(this,[options]);if(!options.format){this.format=new OpenLayers.Format.SOSGetFeatureOfInterest(this.formatOptions);}},destroy:function(){if(this.options&&!this.options.format){this.format.destroy();}
+this.format=null;OpenLayers.Protocol.prototype.destroy.apply(this);},read:function(options){options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options||{});var response=new OpenLayers.Protocol.Response({requestType:"read"});var format=this.format;var data=OpenLayers.Format.XML.prototype.write.apply(format,[format.writeNode("sos:GetFeatureOfInterest",{fois:this.fois})]);response.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleRead,response,options),data:data});return response;},handleRead:function(response,options){if(options.callback){var request=response.priv;if(request.status>=200&&request.status<300){response.features=this.parseFeatures(request);response.code=OpenLayers.Protocol.Response.SUCCESS;}else{response.code=OpenLayers.Protocol.Response.FAILURE;}
+options.callback.call(options.scope,response);}},parseFeatures:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
+if(!doc||doc.length<=0){return null;}
+return this.format.read(doc);},CLASS_NAME:"OpenLayers.Protocol.SOS.v1_0_0"});OpenLayers.Format.SLD.v1_0_0=OpenLayers.Class(OpenLayers.Format.SLD.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd",initialize:function(options){OpenLayers.Format.SLD.v1.prototype.initialize.apply(this,[options]);},CLASS_NAME:"OpenLayers.Format.SLD.v1_0_0"});OpenLayers.Protocol.WFS.v1_0_0=OpenLayers.Class(OpenLayers.Protocol.WFS.v1,{version:"1.0.0",CLASS_NAME:"OpenLayers.Protocol.WFS.v1_0_0"});OpenLayers.Protocol.WFS.v1_1_0=OpenLayers.Class(OpenLayers.Protocol.WFS.v1,{version:"1.1.0",CLASS_NAME:"OpenLayers.Protocol.WFS.v1_1_0"});OpenLayers.Format.OWSContext.v0_3_1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{owc:"http://www.opengis.net/ows-context",gml:"http://www.opengis.net/gml",kml:"http://www.opengis.net/kml/2.2",ogc:"http://www.opengis.net/ogc",ows:"http://www.opengis.net/ows",sld:"http://www.opengis.net/sld",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},VERSION:"0.3.1",schemaLocation:"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd",defaultPrefix:"owc",extractAttributes:true,xy:true,regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},featureNS:"http://mapserver.gis.umn.edu/mapserver",featureType:'vector',geometryName:'geometry',nestingLayerLookup:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);OpenLayers.Format.GML.v2.prototype.setGeometryTypes.call(this);},setNestingPath:function(l){if(l.layersContext){for(var i=0,len=l.layersContext.length;i<len;i++){var layerContext=l.layersContext[i];var nPath=[];var nTitle=l.title||"";if(l.metadata&&l.metadata.nestingPath){nPath=l.metadata.nestingPath.slice();}
+if(nTitle!=""){nPath.push(nTitle);}
+layerContext.metadata.nestingPath=nPath;if(layerContext.layersContext){this.setNestingPath(layerContext);}}}},decomposeNestingPath:function(nPath){var a=[];if(nPath instanceof Array){while(nPath.length>0){a.push(nPath.slice());nPath.pop();}
+a.reverse();}
+return a;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
+if(data&&data.nodeType==9){data=data.documentElement;}
+var context={};this.readNode(data,context);this.setNestingPath({layersContext:context.layersContext});var layers=[];this.processLayer(layers,context);delete context.layersContext;context.layersContext=layers;return context;},processLayer:function(layerArray,layer){if(layer.layersContext){for(var i=0,len=layer.layersContext.length;i<len;i++){var l=layer.layersContext[i];layerArray.push(l);if(l.layersContext){this.processLayer(layerArray,l);}}}},write:function(context,options){var name="OWSContext";this.nestingLayerLookup={};options=options||{};OpenLayers.Util.applyDefaults(options,context);var root=this.writeNode(name,options);this.nestingLayerLookup=null;this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},readers:{"kml":{"Document":function(node,obj){obj.features=new OpenLayers.Format.KML({kmlns:this.namespaces.kml,extractStyles:true}).read(node);}},"owc":{"OWSContext":function(node,obj){this.readChildNodes(node,obj);},"General":function(node,obj){this.readChildNodes(node,obj);},"ResourceList":function(node,obj){this.readChildNodes(node,obj);},"Layer":function(node,obj){var layerContext={metadata:{},visibility:(node.getAttribute("hidden")!="1"),queryable:(node.getAttribute("queryable")=="1"),opacity:((node.getAttribute("opacity")!=null)?parseFloat(node.getAttribute("opacity")):null),name:node.getAttribute("name"),categoryLayer:(node.getAttribute("name")==null),formats:[],styles:[]};if(!obj.layersContext){obj.layersContext=[];}
+obj.layersContext.push(layerContext);this.readChildNodes(node,layerContext);},"InlineGeometry":function(node,obj){obj.features=[];var elements=this.getElementsByTagNameNS(node,this.namespaces.gml,"featureMember");var el;if(elements.length>=1){el=elements[0];}
+if(el&&el.firstChild){var featurenode=(el.firstChild.nextSibling)?el.firstChild.nextSibling:el.firstChild;this.setNamespace("feature",featurenode.namespaceURI);this.featureType=featurenode.localName||featurenode.nodeName.split(":").pop();this.readChildNodes(node,obj);}},"Server":function(node,obj){if((!obj.service&&!obj.version)||(obj.service!=OpenLayers.Format.Context.serviceTypes.WMS)){obj.service=node.getAttribute("service");obj.version=node.getAttribute("version");this.readChildNodes(node,obj);}},"Name":function(node,obj){obj.name=this.getChildValue(node);this.readChildNodes(node,obj);},"Title":function(node,obj){obj.title=this.getChildValue(node);this.readChildNodes(node,obj);},"StyleList":function(node,obj){this.readChildNodes(node,obj.styles);},"Style":function(node,obj){var style={};obj.push(style);this.readChildNodes(node,style);},"LegendURL":function(node,obj){var legend={};obj.legend=legend;this.readChildNodes(node,legend);},"OnlineResource":function(node,obj){obj.url=this.getAttributeNS(node,this.namespaces.xlink,"href");this.readChildNodes(node,obj);}},"ows":OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers.ows,"gml":OpenLayers.Format.GML.v2.prototype.readers.gml,"sld":OpenLayers.Format.SLD.v1_0_0.prototype.readers.sld,"feature":OpenLayers.Format.GML.v2.prototype.readers.feature},writers:{"owc":{"OWSContext":function(options){var node=this.createElementNSPlus("OWSContext",{attributes:{version:this.VERSION,id:options.id||OpenLayers.Util.createUniqueID("OpenLayers_OWSContext_")}});this.writeNode("General",options,node);this.writeNode("ResourceList",options,node);return node;},"General":function(options){var node=this.createElementNSPlus("General");this.writeNode("ows:BoundingBox",options,node);this.writeNode("ows:Title",options.title||'OpenLayers OWSContext',node);return node;},"ResourceList":function(options){var node=this.createElementNSPlus("ResourceList");for(var i=0,len=options.layers.length;i<len;i++){var layer=options.layers[i];var decomposedPath=this.decomposeNestingPath(layer.metadata.nestingPath);this.writeNode("_Layer",{layer:layer,subPaths:decomposedPath},node);}
+return node;},"Server":function(options){var node=this.createElementNSPlus("Server",{attributes:{version:options.version,service:options.service}});this.writeNode("OnlineResource",options,node);return node;},"OnlineResource":function(options){var node=this.createElementNSPlus("OnlineResource",{attributes:{"xlink:href":options.url}});return node;},"InlineGeometry":function(layer){var node=this.createElementNSPlus("InlineGeometry");this.writeNode("gml:boundedBy",layer.getDataExtent(),node);for(var i=0,len=layer.features.length;i<len;i++){this.writeNode("gml:featureMember",layer.features[i],node);}
+return node;},"StyleList":function(styles){var node=this.createElementNSPlus("StyleList");for(var i=0,len=styles.length;i<len;i++){this.writeNode("Style",styles[i],node);}
+return node;},"Style":function(style){var node=this.createElementNSPlus("Style");this.writeNode("Name",style,node);this.writeNode("Title",style,node);this.writeNode("LegendURL",style,node);return node;},"Name":function(obj){var node=this.createElementNSPlus("Name",{value:obj.name});return node;},"Title":function(obj){var node=this.createElementNSPlus("Title",{value:obj.title});return node;},"LegendURL":function(style){var node=this.createElementNSPlus("LegendURL");this.writeNode("OnlineResource",style.legend,node);return node;},"_WMS":function(layer){var node=this.createElementNSPlus("Layer",{attributes:{name:layer.params.LAYERS,queryable:layer.queryable?"1":"0",hidden:layer.visibility?"0":"1",opacity:layer.opacity?layer.opacity:null}});this.writeNode("ows:Title",layer.name,node);this.writeNode("ows:OutputFormat",layer.params.FORMAT,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.WMS,version:layer.params.VERSION,url:layer.url},node);if(layer.metadata.styles&&layer.metadata.styles.length>0){this.writeNode("StyleList",layer.metadata.styles,node);}
+return node;},"_Layer":function(options){var layer,subPaths,node,title;layer=options.layer;subPaths=options.subPaths;node=null;title=null;if(subPaths.length>0){var path=subPaths[0].join("/");var index=path.lastIndexOf("/");node=this.nestingLayerLookup[path];title=(index>0)?path.substring(index+1,path.length):path;if(!node){node=this.createElementNSPlus("Layer");this.writeNode("ows:Title",title,node);this.nestingLayerLookup[path]=node;}
+options.subPaths.shift();this.writeNode("_Layer",options,node);return node;}else{if(layer instanceof OpenLayers.Layer.WMS){node=this.writeNode("_WMS",layer);}else if(layer instanceof OpenLayers.Layer.Vector){if(layer.protocol instanceof OpenLayers.Protocol.WFS.v1){node=this.writeNode("_WFS",layer);}else if(layer.protocol instanceof OpenLayers.Protocol.HTTP){if(layer.protocol.format instanceof OpenLayers.Format.GML){layer.protocol.format.version="2.1.2";node=this.writeNode("_GML",layer);}else if(layer.protocol.format instanceof OpenLayers.Format.KML){layer.protocol.format.version="2.2";node=this.writeNode("_KML",layer);}}else{this.setNamespace("feature",this.featureNS);node=this.writeNode("_InlineGeometry",layer);}}
+if(layer.options.maxScale){this.writeNode("sld:MinScaleDenominator",layer.options.maxScale,node);}
+if(layer.options.minScale){this.writeNode("sld:MaxScaleDenominator",layer.options.minScale,node);}
+this.nestingLayerLookup[layer.name]=node;return node;}},"_WFS":function(layer){var node=this.createElementNSPlus("Layer",{attributes:{name:layer.protocol.featurePrefix+":"+layer.protocol.featureType,hidden:layer.visibility?"0":"1"}});this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.WFS,version:layer.protocol.version,url:layer.protocol.url},node);return node;},"_InlineGeometry":function(layer){var node=this.createElementNSPlus("Layer",{attributes:{name:this.featureType,hidden:layer.visibility?"0":"1"}});this.writeNode("ows:Title",layer.name,node);this.writeNode("InlineGeometry",layer,node);return node;},"_GML":function(layer){var node=this.createElementNSPlus("Layer");this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.GML,url:layer.protocol.url,version:layer.protocol.format.version},node);return node;},"_KML":function(layer){var node=this.createElementNSPlus("Layer");this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.KML,version:layer.protocol.format.version,url:layer.protocol.url},node);return node;}},"gml":OpenLayers.Util.applyDefaults({"boundedBy":function(bounds){var node=this.createElementNSPlus("gml:boundedBy");this.writeNode("gml:Box",bounds,node);return node;}},OpenLayers.Format.GML.v2.prototype.writers.gml),"ows":OpenLayers.Format.OWSCommon.v1_0_0.prototype.writers.ows,"sld":OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld,"feature":OpenLayers.Format.GML.v2.prototype.writers.feature},CLASS_NAME:"OpenLayers.Format.OWSContext.v0_3_1"});
+require.define('ripple', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var omgwtf = require('ripple/omgwtf'),
+    db = require('ripple/db'),
+    xhr = require('ripple/xhr'),
+    geo = require('ripple/geo'),
+    fileSystem = require('ripple/fileSystem'),
+    fs = require('ripple/dbfs'),
+    platform = require('ripple/platform'),
+    devices = require('ripple/devices'),
+    widgetConfig = require('ripple/widgetConfig'),
+    deviceSettings = require('ripple/deviceSettings'),
+    sensorSettings = require('ripple/sensorSettings'),
+    ui = require('ripple/ui'),
+    appcache = require('ripple/appcache'),
+    _self = {
+        boot: function (booted) {
+            // techdebt (event registration timing)
+            // require('ripple/platform/webworks.core/2.0.0/fsCache');
+
+            jWorkflow.order(omgwtf.initialize, omgwtf)
+                 .andThen(appcache.initialize, appcache)
+                 .andThen(db.initialize, db)
+                 .andThen(xhr.initialize, xhr)
+                 .andThen(geo.initialize, geo)
+                 .andThen(fileSystem.initialize, fileSystem)
+                 .andThen(fs.initialize, fs)
+                 .andThen(devices.initialize, devices)
+                 .andThen(platform.initialize, platform)
+                 .andThen(widgetConfig.initialize, widgetConfig)
+                 .andThen(deviceSettings.initialize, deviceSettings)
+                 .andThen(ui.initialize, ui)
+                 .start(booted);
+        }
+    };
+
+module.exports = _self;
+
+});
+require.define('ripple/xhr/jsonp', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    exception = require('ripple/exception'),
+    utils = require('ripple/utils'),
+    helpers = require('ripple/xhr/helpers'),
+    _console = require('ripple/console'),
+    XHR = require('ripple/xhr/base');
+
+function _XMLHttpRequest() {
+    var xhr = new XHR(),
+        origMethods = {
+            setRequestHeader: xhr.setRequestHeader,
+            getResponseHeader: xhr.getResponseHeader,
+            getAllResponseHeaders: xhr.getAllResponseHeaders,
+            open: xhr.open,
+            send: xhr.send,
+            abort: xhr.abort
+        },
+        _jxhr = new window.jXHR(),
+        _sendFlag = false,
+        _headers = [],
+        _errorFlag = false,
+        _url,
+        _async;
+
+    function _localURI() {
+        return _url && helpers.isLocalRequest(_url);
+    }
+
+    function _set(prop, value) {
+        xhr.__defineGetter__(prop, function () {
+            return value;
+        });
+    }
+
+    function _reset() {
+        _set("response", "");
+        _set("responseText", "");
+        _set("responseXML", null);
+    }
+
+    xhr.setRequestHeader = function (header, value) {
+        if (_localURI()) {
+            origMethods.setRequestHeader.apply(xhr, Array.prototype.slice.call(arguments));
+        } else {
+            _console.error("XMLHttpRequest :: setRequestHeader does not work with JSONP.");
+        }
+    };
+
+    xhr.getResponseHeader = function (header) {
+        return _localURI() ?
+                origMethods.getAllResponseHeaders.apply(xhr, [header]) :
+                _headers[header] || null;
+    };
+
+    xhr.getAllResponseHeaders = function () {
+        return _localURI() ?
+                origMethods.getAllResponseHeaders.apply(xhr) :
+                utils.reduce(_headers, function (str, value, key) {
+                    return str + key + ": " + value + '\n';
+                }, "").replace(/\n$/, '');
+    };
+
+    xhr.open = function (method, url, async) {
+        _url = url;
+        _async = async !== false ? true : false;
+
+        if (_localURI()) {
+            origMethods.open.apply(xhr, Array.prototype.slice.call(arguments));
+        } else {
+            _reset();
+            method = method.toUpperCase();
+
+            if (method === "POST") {
+                //HACK: Switch the method to get for now to simulate post
+                method = "GET";
+            }
+
+            if (method !== "GET") {
+                exception.raise(exception.types.MethodNotImplemented, "Method: " + method + " not supported!");
+            }
+
+            _jxhr.onreadystatechange = function (data) {
+                var response;
+
+                try {
+                    _set("readyState", _jxhr.readyState);
+
+                    if (xhr.readyState === xhr.DONE) {
+                        _sendFlag = false;
+                        _set("status", data.status);
+                        _set("statusText", data.statusText);
+                        _headers = data.headers;
+
+                        if (data.responseXML) {
+                            response = new DOMParser().parseFromString(unescape(data.responseXML), "text/xml");
+                            _set("responseXML", response);
+                        } else {
+                            response = unescape(data.responseText);
+                            _set("responseText", response);
+                        }
+
+                        _set("response", response);
+                    }
+
+                    if (typeof xhr.onreadystatechange === "function") {
+                        xhr.onreadystatechange.apply(xhr);
+                    }
+                } catch (e) {
+                    exception.handle(e);
+                }
+            };
+
+            _jxhr.onerror = xhr.onerror;
+            _jxhr.open(method, constants.API_URL + "/jsonp_xhr_proxy?callback=?&tinyhippos_apikey=ABC&tinyhippos_rurl=" + escape(url));
+        }
+    };
+
+    xhr.send = function (data) {
+        if (_localURI()) {
+            origMethods.send(data);
+            return;
+        }
+
+        if (!_async) {
+            exception.raise(exception.types.MethodNotImplemented, "Synchronous not supported.");
+        }
+
+        if (xhr.readyState !== xhr.OPENED || _sendFlag === true) {
+            exception.raise(exception.types.InvalidState, "Ready state should be OPENED (1)");
+        }
+
+        _errorFlag = false;
+        _sendFlag = true;
+        data = null;
+
+        _jxhr.send();
+    };
+
+    xhr.abort = function () {
+        if (_localURI()) {
+            origMethods.abort();
+            return;
+        }
+
+        _reset();
+
+        _errorFlag = true;
+
+        if (xhr.readyState === xhr.UNSENT ||
+                (xhr.readyState === xhr.OPENED && _sendFlag === false) ||
+                xhr.readyState === xhr.DONE) {
+            _set("readyState", xhr.UNSENT);
+        } else {
+            _set("readyState", xhr.DONE);
+            _sendFlag = false;
+
+            if (typeof xhr.onreadystatechange === "function") {
+                xhr.onreadystatechange.apply(xhr);
+            }
+        }
+
+        _jxhr.onreadystatechange = null;
+
+        if (xhr.onabort) {
+            xhr.onabort.apply(xhr, arguments);
+        }
+    };
+
+    return xhr;
+}
+
+module.exports = _XMLHttpRequest;
+
+});
+require.define('ripple/xhr/cors', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var helpers = require('ripple/xhr/helpers'),
+    constants = require('ripple/constants'),
+    _console = require('ripple/console'),
+    XHR = require('ripple/xhr/base');
+
+function _XMLHttpRequest() {
+    var xhr = new XHR(),
+        origMethods = {
+            setRequestHeader: xhr.setRequestHeader,
+            open: xhr.open
+        };
+
+    xhr.setRequestHeader = function (header, value) {
+        // This is done to get around jQuery 1.3.2 setting a header that it shouldn't
+        if (header && header.toUpperCase() !== "X-REQUESTED-WITH") {
+            origMethods.setRequestHeader.apply(xhr, Array.prototype.slice.call(arguments));
+        }
+    };
+
+    xhr.open = function (method, url, async, user, password) {
+        if (!helpers.isLocalRequest(url)) {
+            url = constants.API_URL + "/xhr_proxy?tinyhippos_apikey=ABC&tinyhippos_rurl=" + escape(url);
+        }
+
+        origMethods.open.apply(xhr, Array.prototype.slice.call(arguments));
+    };
+
+    return xhr;
+}
+
+module.exports = _XMLHttpRequest;
+
+});
+require.define('ripple/xhr/helpers', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    db = require('ripple/db');
+
+module.exports = {
+    isLocalRequest: function (url) {
+        return (!!(url.match(constants.REGEX.LOCAL_URI)) || !url.match(constants.REGEX.EXTERNAL_URI)) || !!(location.host && url.match(location.host));
+    },
+
+    proxyEnabled: function () {
+        var isDisabled = db.retrieve(constants.XHR.PROXY_DISABLED_BUTTON);
+        return !isDisabled || isDisabled === "false" ? true : false;
+    }
+};
+
+});
+require.define('ripple/xhr/base', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var XHR = window.XMLHttpRequest;
+
+function _handle(object, key) {
+    return function () {
+        return object[key].apply(object, Array.prototype.slice.call(arguments));
+    };
+}
+
+function _getter(object, key) {
+    return function () {
+        return object[key];
+    };
+}
+
+function _setter(object, key) {
+    return function (val) {
+        object[key] = val;
+    };
+}
+
+function _writeable(obj) {
+    var newObj = {},
+        key;
+
+    // need prototypes
+    for (key in obj) {
+        /* HACK: this seems wrong and makes babies cry. */
+        /* new attribute, obj["responseBlob"], exists on Chrome 21.0.1180.57.
+           But this attribute is DOMException (INVALID_STATE_ERR), we skip it */
+        if (key === "responseBlob") {
+            continue;
+        }
+        if (typeof obj[key] === "function") {
+            newObj[key] = _handle(obj, key);
+        } else {
+            newObj.__defineGetter__(key, _getter(obj, key));
+            newObj.__defineSetter__(key, _setter(obj, key));
+        }
+    }
+
+    return newObj;
+}
+
+function _XMLHttpRequest() {
+    var Xhr = require('ripple/emulatorBridge').xhr() || XHR;
+    return _writeable(new Xhr());
+}
+
+module.exports = _XMLHttpRequest;
+
+});
+require.define('ripple/devices/QVGA', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "QVGA",
+    "name": "Generic - QVGA (240X320)",
+    "osName": "Generic",
+    "osVersion": "Generic",
+    "manufacturer": "Generic",
+    "model": "Generic",
+    "uuid": "42",
+    "firmware": "Generic",
+
+    "screen": {
+        "width": 240,
+        "height": 320
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 240,
+            "height": 320,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 320,
+            "height": 240,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "browser": ["Generic"],
+    "ppi": 96,
+    "platforms": ["wac", "web", "phonegap", "tizen"],
+    "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
+};
+
+});
+require.define('ripple/devices/Legend', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "Legend",
+    "name": "HTC Legend",
+    "osName": "Android",
+    "osVersion": "1.6",
+    "manufacturer": "HTC",
+    "model": "Legend",
+    "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
+    "firmware": "1.6",
+
+    "screen": {
+        "width": 320,
+        "height": 480
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 320,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 480,
+            "height": 320,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 180.3,
+    "userAgent": "Mozilla/5.0 (Linux; U; Android 2.1; fr-fr; HTC Legend 1.32.163.1 Build/ERD79) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17",
+    "browser": ["Webkit", "Presto"],
+    "platforms": ["web", "phonegap"]
+};
+
+});
+require.define('ripple/devices/NokiaN8', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "NokiaN8",
+    "name": "Nokia N8",
+    "model": "N8",
+    "osName": "SymbianOS",
+    "uuid": "42",
+    "osVersion": "3",
+    "firmware": "3",
+    "manufacturer": "Nokia",
+
+    "screen": {
+        "width": 360,
+        "height": 640
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 360,
+            "height": 640,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 640,
+            "height": 360,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 209.8,
+    "userAgent": "(Symbian/3; S60/5.2 Mozilla/5.0; NokiaN8-00/10.0.000; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.2",
+    "browser": ["Webkit", "Presto"],
+    "platforms": ["web", "phonegap"],
+
+    "notes": {
+        "1": "<a href=\"http://www.forum.nokia.com/Devices/Device_specifications/N8-00/\" target=\"_blank\">Specs</a>"
+    }
+};
+
+});
+require.define('ripple/devices/Nexus', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "Nexus",
+    "name": "Nexus One",
+    "manufacturer": "HTC",
+    "model": "Nexux One",
+    "firmware": "2.x.x",
+    "osName": "Android",
+    "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
+    "osVersion": "2.x.x",
+
+    "screen": {
+        "width": 480,
+        "height": 800
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 480,
+            "height": 800,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 800,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 252.15,
+    "userAgent": "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17",
+    "browser": ["Webkit", "Presto"],
+    "platforms": ["web", "phonegap"],
+
+    "notes": {
+        "1": "<a href=\"http://www.google.com/phone/static/en_US-nexusone_tech_specs.html\" target=\"_blank\">Specs</a>"
+    }
+};
+
+});
+require.define('ripple/devices/Playbook', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "Playbook",
+    "name": "BlackBerry Playbook",
+    "model": "Playbook",
+    "osName": "BlackBerry Tablet OS (QNX)",
+    "uuid": "42",
+    "osVersion": "QNX",
+    "firmware": "6",
+    "manufacturer": "Research In Motion",
+
+    "skin": "Playbook",
+
+    "capabilities": [
+        "input.touch",
+        "location.gps",
+        "media.audio.capture",
+        "media.video.capture",
+        "media.recording",
+        "network.bluetooth",
+        "network.wlan"
+    ],
+
+    "screen": {
+        "width": 1024,
+        "height": 600
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 1024,
+            "height": 600,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 600,
+            "height": 1024,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "defaultOrientation": "landscape",
+
+    "ppi": 169.55,
+    "userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 1.0.0; en-US) AppleWebKit/534.8+ (KHTML, like Gecko) Version/0.0.1 Safari/534.8+.",
+    "browser": ["Webkit"],
+    "platforms": ["web", "webworks.tablet", "phonegap"]
+};
+
+});
+require.define('ripple/devices/NokiaN97', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "NokiaN97",
+    "name": "Nokia N97/5800 (touch)",
+    "manufacturer": "Nokia",
+    "model": "N97",
+    "osName": "S60",
+    "osVersion": "v5",
+    "firmware": "v5",
+    "uuid": "42",
+
+    "screen": {
+        "width": 360,
+        "height": 640
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 360,
+            "height": 640,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 640,
+            "height": 360,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 232,
+    "browser": ["Webkit", "Presto"],
+    "userAgent": "?",
+    "platforms": ["web", "phonegap"]
+};
+
+});
+require.define('ripple/devices/Torch9800', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "Torch9800",
+    "name": "BlackBerry Torch 9800",
+    "model": "9800",
+    "osName": "BlackBerry OS",
+    "uuid": "42",
+    "osVersion": "6",
+    "firmware": "6",
+    "manufacturer": "Research In Motion",
+
+    "skin": "Torch9800",
+
+    "capabilities": [
+        "input.touch",
+        "location.gps",
+        "location.maps",
+        "media.audio.capture",
+        "media.video.capture",
+        "media.recording",
+        "storage.memorycard",
+        "network.bluetooth",
+        "network.wlan",
+        "network.3gpp"
+    ],
+
+    "screen": {
+        "width": 360,
+        "height": 480
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 360,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 480,
+            "height": 360,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 188.68,
+    "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap", "webworks.handset"]
+};
+
+});
+require.define('ripple/devices/G1', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "G1",
+    "name": "HTC G1",
+    "model": "G1",
+    "osName": "Android",
+    "osVersion": "1.6",
+    "firmware": "1.6",
+    "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
+    "manufacturer": "HTC",
+
+    "screen": {
+        "width": 320,
+        "height": 480
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 320,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 480,
+            "height": 320,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "browser": ["Webkit", "Presto"],
+    "ppi": 180.28,
+    "platforms": ["web", "phonegap"],
+    "userAgent": "Mozilla/5.0 (Linux; U; Android 1.0; en-us; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2",
+
+    "notes": {
+        "1": "<a href=\"http://www.htc.com/www/product/g1/specification.html\" target=\"_blank\">Specs</a>"
+    }
+};
+
+});
+require.define('ripple/devices/Bold9900', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "Bold9900",
+    "name": "BlackBerry Bold 9900",
+    "model": "9900",
+    "osName": "BlackBerry OS",
+    "uuid": "42",
+    "osVersion": "7",
+    "firmware": "7",
+    "manufacturer": "Research In Motion",
+
+    "skin": "Bold9900",
+
+    "capabilities": [
+        "input.touch",
+        "location.gps",
+        "location.maps",
+        "media.audio.capture",
+        "media.video.capture",
+        "media.recording",
+        "storage.memorycard",
+        "network.bluetooth",
+        "network.wlan",
+        "network.3gpp"
+    ],
+
+    "screen": {
+        "width": 640,
+        "height": 480
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 640,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 287.00,
+    "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.141 Mobile Safari/534.1",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap", "webworks.handset"]
+};
+
+});
+require.define('ripple/devices/Style9670', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "Style9670",
+    "name": "BlackBerry Style 9670",
+    "model": "9670",
+    "osName": "BlackBerry OS",
+    "uuid": "42",
+    "osVersion": "6",
+    "firmware": "6",
+    "manufacturer": "Research In Motion",
+
+    "skin": "Style9670",
+
+    "capabilities": [
+        "location.gps",
+        "location.maps",
+        "media.audio.capture",
+        "media.video.capture",
+        "media.recording",
+        "storage.memorycard",
+        "network.bluetooth",
+        "network.wlan",
+        "network.3gpp"
+    ],
+
+    "screen": {
+        "width": 360,
+        "height": 400
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 360,
+            "height": 400,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 200,
+    "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9670; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap", "webworks.handset"]
+};
+
+});
+require.define('ripple/devices/Torch9860-9850', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "Torch9860-9850",
+    "name": "BlackBerry Torch 9860/9850",
+    "model": "9860-9850",
+    "osName": "BlackBerry OS",
+    "uuid": "42",
+    "osVersion": "7",
+    "firmware": "7",
+    "manufacturer": "Research In Motion",
+
+    "skin": "Torch9860-9850",
+
+    "capabilities": [
+        "input.touch",
+        "location.gps",
+        "location.maps",
+        "media.audio.capture",
+        "media.video.capture",
+        "media.recording",
+        "storage.memorycard",
+        "network.bluetooth",
+        "network.wlan",
+        "network.3gpp"
+    ],
+
+    "screen": {
+        "width": 480,
+        "height": 800
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 480,
+            "height": 800,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 800,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 253,
+    "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9860; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap", "webworks.handset"]
+};
+
+});
+require.define('ripple/devices/PalmPre', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "PalmPre",
+    "name": "Palm Pre",
+    "manufacturer": "Palm",
+    "model": "Pre",
+    "firmware": "1.x",
+    "osName": "WebOS",
+    "osVersion": "1.x",
+
+    "screen": {
+        "width": 320,
+        "height": 480
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 320,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 480,
+            "height": 320,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 186.09,
+    "userAgent": "Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap"],
+
+    "notes": {
+        "1": "<a href=\"http://www.palm.com/us/products/phones/pre/#tab2\" target=\"_blank\">Specs</a>"
+    }
+};
+
+});
+require.define('ripple/devices/Bold9700', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "Bold9700",
+    "name": "BlackBerry Bold 9700",
+    "model": "9700",
+    "osName": "BlackBerry OS",
+    "uuid": "42",
+    "osVersion": "6",
+    "firmware": "6",
+    "manufacturer": "Research In Motion",
+
+    "skin": "Bold9700",
+
+    "capabilities": [
+        "input.touch",
+        "location.gps",
+        "location.maps",
+        "media.audio.capture",
+        "media.video.capture",
+        "media.recording",
+        "storage.memorycard",
+        "network.bluetooth",
+        "network.wlan",
+        "network.3gpp"
+    ],
+
+    "screen": {
+        "width": 480,
+        "height": 360
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 480,
+            "height": 360,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 245.00,
+    "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9700; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap", "webworks.handset"]
+};
+
+});
+require.define('ripple/devices/HVGA', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "group": "Generic Devices",
+
+    "id": "HVGA",
+    "name": "HVGA (320x480)",
+    "osName": "Generic",
+    "osVersion": "Generic",
+    "manufacturer": "Generic",
+    "model": "Generic",
+    "uuid": "42",
+    "firmware": "Generic",
+
+    "screen": {
+        "width": 320,
+        "height": 480
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 320,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 480,
+            "height": 320,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "browser": ["Generic"],
+    "ppi": 96,
+    "platforms": ["wac", "web", "phonegap", "tizen"],
+    "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
+};
+
+});
+require.define('ripple/devices/FWVGA', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "group": "Generic Devices",
+
+    "id": "FWVGA",
+    "name": "Generic - FWVGA (480x854)",
+    "osName": "Generic",
+    "osVersion": "Generic",
+    "manufacturer": "Generic",
+    "model": "Generic",
+    "uuid": "42",
+    "firmware": "Generic",
+
+    "screen": {
+        "width": 480,
+        "height": 854
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 480,
+            "height": 854,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 854,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "browser": ["Generic"],
+    "ppi": 96,
+    "platforms": ["web", "phonegap"],
+    "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
+};
+
+});
+require.define('ripple/devices/Curve9300', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "Curve9300",
+    "name": "BlackBerry Curve 9300",
+    "model": "9300",
+    "osName": "BlackBerry OS",
+    "uuid": "42",
+    "osVersion": "6",
+    "firmware": "6",
+    "manufacturer": "Research In Motion",
+
+    "skin": "Curve9300",
+
+    "capabilities": [
+        "location.gps",
+        "location.maps",
+        "media.audio.capture",
+        "media.video.capture",
+        "media.recording",
+        "storage.memorycard",
+        "network.bluetooth",
+        "network.wlan",
+        "network.3gpp"
+    ],
+
+    "screen": {
+        "width": 320,
+        "height": 240
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 320,
+            "height": 240,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 163,
+    "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9300; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap", "webworks.handset"]
+};
+
+});
+require.define('ripple/devices/HD', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = {
+    "id": "HD",
+    "name": "HD (720x1280)",
+    "osName": "Generic",
+    "osVersion": "Generic",
+    "manufacturer": "Generic",
+    "model": "Generic",
+    "uuid": "42",
+    "firmware": "Generic",
+
+    "screen": {
+        "width": 720,
+        "height": 1280
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 720,
+            "height": 1280,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 1280,
+            "height": 720,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 96,
+    "browser": ["Generic"],
+    "platforms": ["wac", "web", "phonegap", "tizen"],
+    "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
+};
+
+});
+require.define('ripple/devices/WQVGA', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "WQVGA",
+    "name": "Generic - WQVGA (240x480)",
+    "osName": "Generic",
+    "osVersion": "Generic",
+    "manufacturer": "Generic",
+    "model": "Generic",
+    "uuid": "42",
+    "firmware": "Generic",
+
+    "screen": {
+        "width": 240,
+        "height": 480
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 240,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 480,
+            "height": 240,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 96,
+    "browser": ["Generic"],
+    "platforms": ["wac", "web", "phonegap", "tizen"],
+    "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
+};
+
+});
+require.define('ripple/devices/WSVGA', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "WSVGA",
+    "name": "WSVGA (600x1024)",
+    "osName": "Generic",
+    "osVersion": "Generic",
+    "manufacturer": "Generic",
+    "model": "Generic",
+    "uuid": "42",
+    "firmware": "Generic",
+
+    "screen": {
+        "width": 600,
+        "height": 1024
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 600,
+            "height": 1024,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 1024,
+            "height": 600,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 96,
+    "browser": ["Generic"],
+    "platforms": ["wac", "web", "phonegap", "tizen"],
+    "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
+};
+
+});
+require.define('ripple/devices/WVGA', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "WVGA",
+    "name": "WVGA (480x800)",
+    "osName": "Generic",
+    "osVersion": "Generic",
+    "manufacturer": "Generic",
+    "model": "Generic",
+    "uuid": "42",
+    "firmware": "Generic",
+
+    "screen": {
+        "width": 480,
+        "height": 800
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 480,
+            "height": 800,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 800,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 96,
+    "browser": ["Generic"],
+    "platforms": ["wac", "web", "phonegap", "tizen"],
+    "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
+};
+
+});
+require.define('ripple/devices/Wave', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "Wave",
+    "name": "Samsung Wave",
+    "manufacturer": "Samsung",
+    "model": "Wave",
+    "firmware": "n/a",
+    "osName": "Bada",
+    "osVersion": "n/a",
+
+    "screen": {
+        "width": 480,
+        "height": 800
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 480,
+            "height": 800,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 800,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 283,
+    "userAgent": "?",
+    "browser": ["Webkit"],
+    "platforms": ["web"]
+};
+
+});
+require.define('ripple/devices/iPhone3', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "iPhone3",
+    "name": "iPhone 3G/3Gs/4/4s",
+    "model": "3G",
+    "osName": "iPhone",
+    "osVersion": "3",
+    "firmware": "3",
+    "uuid": "e0101010d38bde8e6740011221af335301010333",
+    "manufacturer": "Apple",
+
+    "screen": {
+        "width": 320,
+        "height": 480
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 320,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 480,
+            "height": 320,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "overrides": {
+        "api": {
+            "phonegap": {
+                "viewPort": {
+                    "portrait": {
+                        "width": 320,
+                        "height": 480,
+                        "paddingTop": 0,
+                        "paddingLeft": 0
+                    },
+                    "landscape": {
+                        "width": 480,
+                        "height": 320,
+                        "paddingTop": 0,
+                        "paddingLeft": 0
+                    }
+                }
+            }
+        }
+    },
+
+    "ppi": 164.8,
+    "userAgent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/1A542a Safari/419.3",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap"]
+};
+
+});
+require.define('ripple/devices/PalmPre2', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "PalmPre2",
+    "name": "Palm Pre 2",
+    "manufacturer": "Palm",
+    "model": "Pre",
+    "firmware": "2.x",
+    "osName": "WebOS",
+    "osVersion": "2.x",
+
+    "screen": {
+        "width": 320,
+        "height": 480
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 320,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 480,
+            "height": 320,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 186.09,
+    // TODO :: not exactly the correct userAgent webkit version is probably different
+    "userAgent": "Mozilla/5.0 (webOS/2.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/2.0",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap"],
+
+    "notes": {
+        "1": "<a href=\"http://www.palm.com/us/products/phones/pre2/#tab2\" target=\"_blank\">Specs</a>"
+    }
+};
+
+});
+require.define('ripple/devices/Curve9350-9360-9370', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "Curve9350-9360-9370",
+    "name": "BlackBerry Curve 9350/9360/9370",
+    "model": "9350-9360-9370",
+    "osName": "BlackBerry OS",
+    "uuid": "42",
+    "osVersion": "7",
+    "firmware": "7",
+    "manufacturer": "Research In Motion",
+
+    "skin": "Curve9350-9360-9370",
+
+    "capabilities": [
+        "input.touch",
+        "location.gps",
+        "location.maps",
+        "media.audio.capture",
+        "media.video.capture",
+        "media.recording",
+        "storage.memorycard",
+        "network.bluetooth",
+        "network.wlan",
+        "network.3gpp"
+    ],
+
+    "screen": {
+        "width": 480,
+        "height": 360
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 480,
+            "height": 360,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 246.00,
+    "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9350; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap", "webworks.handset"]
+};
+
+});
+require.define('ripple/devices/iPad', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "iPad",
+    "name": "iPad",
+    "model": "iPad",
+    "osName": "iOS",
+    "uuid": "e0101010d38bde8e6740011221af335301010333",
+    "osVersion": "1.6",
+    "firmware": "1.6",
+    "manufacturer": "Apple",
+
+    "screen": {
+        "width": 768,
+        "height": 1024
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 768,
+            "height": 1024,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 1024,
+            "height": 768,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 132,
+    "userAgent": "Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap"],
+
+    "notes": {
+        "1": "<a href=\"http://www.apple.com/ipad/specs/\" target=\"_blank\">Specs</a>"
+    }
+};
+
+});
+require.define('ripple/devices/NexusS', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id" : "NexusS",
+    "name": "Nexus S",
+    "manufacturer": "Samsung",
+    "model": "Nexux S",
+    "firmware": "2.3.x",
+    "osName": "Android",
+    "uuid" : "F54E13F1-C1B7-4212-BFA8-AB3C9C3F088F",
+    "osVersion": "2.3.x",
+
+    "screen": {
+        "width": 480,
+        "height": 800
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 480,
+            "height": 800,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 800,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 235,
+    "userAgent": "Mozilla/5.0 (Linux; U; Android 2.3.2; en-us; Nexus S Build/GRH78C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+    "browser": ["Webkit", "Presto"],
+    "platforms": ["web", "phonegap"],
+
+    "notes": {
+        "1": "<a href=\"http://www.google.com/nexus/#/tech-specs\" target=\"_blank\">Specs</a>"
+    }
+
+};
+
+});
+require.define('ripple/devices/Torch9810', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "Torch9810",
+    "name": "BlackBerry Torch 9810",
+    "model": "9810",
+    "osName": "BlackBerry OS",
+    "uuid": "42",
+    "osVersion": "7",
+    "firmware": "7",
+    "manufacturer": "Research In Motion",
+
+    "skin": "Torch9810",
+
+    "capabilities": [
+        "input.touch",
+        "location.gps",
+        "location.maps",
+        "media.audio.capture",
+        "media.video.capture",
+        "media.recording",
+        "storage.memorycard",
+        "network.bluetooth",
+        "network.wlan",
+        "network.3gpp"
+    ],
+
+    "screen": {
+        "width": 480,
+        "height": 640
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 480,
+            "height": 640,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 640,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 253,
+    "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9810; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap", "webworks.handset"]
+};
+
+});
+require.define('ripple/devices/Tattoo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "Tattoo",
+    "name": "HTC Tattoo",
+    "manufacturer": "HTC",
+    "model": "Tattoo",
+    "firmware": "n/a",
+    "osVersion": "1.6",
+    "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
+    "osName": "Android",
+
+    "screen": {
+        "width": 240,
+        "height": 320
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 240,
+            "height": 320,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 142.9,
+    "userAgent": "Mozilla/5.0 (Linux; U; Android 1.6; en-us; HTC_TATTOO_A3288 Build/DRC79) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap"]
+};
+
+});
+require.define('ripple/devices/Pearl9100', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    "id": "Pearl9100",
+    "name": "BlackBerry Pearl 9100",
+    "model": "9100",
+    "osName": "BlackBerry OS",
+    "uuid": "42",
+    "osVersion": "6",
+    "firmware": "6",
+    "manufacturer": "Research In Motion",
+
+    "skin": "Pearl9100",
+
+    "capabilities": [
+        "location.gps",
+        "location.maps",
+        "media.audio.capture",
+        "media.video.capture",
+        "media.recording",
+        "storage.memorycard",
+        "network.bluetooth",
+        "network.wlan",
+        "network.3gpp"
+    ],
+
+    "screen": {
+        "width": 360,
+        "height": 400
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 360,
+            "height": 400,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 239,
+    "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9100; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap", "webworks.handset"]
+};
+
+});
+require.define('ripple/devices/HPPre3', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "HPPre3",
+    "name": "HP Pre 3",
+    "manufacturer": "HP",
+    "model": "Pre",
+    "firmware": "2.x",
+    "osName": "WebOS",
+    "osVersion": "2.x",
+
+    "screen": {
+        "width": 480,
+        "height": 800
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 480,
+            "height": 800,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 800,
+            "height": 480,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 260,
+    // TODO :: not exactly the correct userAgent webkit version is probably different
+    "userAgent": "Mozilla/5.0 (webOS/2.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/2.0",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap"],
+
+    "notes": {
+        "1": "<a href=\"http://www.palm.com/us/products/phones/pre3/index.html\" target=\"_blank\">Specs</a>"
+    }
+};
+
+});
+require.define('ripple/devices/HPVeer', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "id": "HPVeer",
+    "name": "HP Veer",
+    "manufacturer": "HP",
+    "model": "Veer",
+    "firmware": "2.x",
+    "osName": "WebOS",
+    "osVersion": "2.x",
+
+    "screen": {
+        "width": 320,
+        "height": 400
+    },
+    "viewPort": {
+        "portrait": {
+            "width": 320,
+            "height": 400,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        },
+        "landscape": {
+            "width": 400,
+            "height": 320,
+            "paddingTop": 0,
+            "paddingLeft": 0
+        }
+    },
+
+    "ppi": 197,
+    // TODO :: not exactly the correct userAgent webkit version is probably different
+    "userAgent": "Mozilla/5.0 (webOS/2.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/2.0",
+    "browser": ["Webkit"],
+    "platforms": ["web", "phonegap"],
+
+    "notes": {
+        "1": "<a href=\"http://www.palm.com/us/products/phones/veer/index.html\" target=\"_blank\">Specs</a>"
+    }
+};
+
+});
+require.define('ripple/fileSystem', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    db = require('ripple/db'),
+    exception = require('ripple/exception'),
+    event = require('ripple/event'),
+    _console = require('ripple/console'),
+    utils = require('ripple/utils'),
+    _fileSystemPaths = {
+        "photos": { "uri": "" },
+        "videos": { "uri": "" },
+        "music": { "uri": "" },
+        "downloads": { "uri": "" },
+        "widgethome": { "uri": "" }
+    },
+    _fileSystemRegex = {
+        "photos": { "virtualPathRegex": /^\/virtual\/photos\//i },
+        "videos": { "virtualPathRegex": /^\/virtual\/videos\//i },
+        "music": { "virtualPathRegex": /^\/virtual\/music\//i },
+        "downloads": { "virtualPathRegex": /^\/virtual\/downloads\//i },
+        "widgethome": { "virtualPathRegex": /^\/virtual\/widgethome\//i }
+    },
+    _overrides = {};
+
+module.exports = {
+    initialize: function () {
+        _fileSystemPaths = db.retrieveObject(constants.FILESYSTEM.PERSISTENCE_KEY) || _fileSystemPaths;
+        _fileSystemPaths.widgethome.uri = window.location.protocol + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/') + 1);
+    },
+
+    getURI: function getURI(origURI) {
+        var newURI = origURI,
+            found = false;
+
+        if (_overrides[origURI]) {
+            return _overrides[origURI];
+        }
+
+        utils.forEach(_fileSystemPaths, function (value, key) {
+            if (found) {
+                return;
+            }
+
+            var uri = value.uri.replace(/\/$/, "");
+            if (origURI.match(_fileSystemRegex[key].virtualPathRegex)) {
+                newURI = origURI.replace(_fileSystemRegex[key].virtualPathRegex, uri + "/");
+                found = true;
+            }
+        });
+
+        return newURI;
+    },
+
+    exists: function (path) {
+        try {
+            var scrubbedUri = this.getURI(path),
+                xhr = new XMLHttpRequest();
+
+            xhr.open("GET", scrubbedUri, false);
+            xhr.send();
+
+            //HACK: this should return maybe for 403
+            return xhr.status !== 404;
+        }
+        catch (e) {
+            exception.handle(e);
+            _console.log("failed to check if [" + path + "] exists");
+            return false;
+        }
+    },
+
+
+    getFileSystemPaths: function getFileSystemPaths() {
+        return utils.copy(_fileSystemPaths);
+    },
+
+    updateFileSystemPaths: function updateFileSystemPaths(filePathsObject) {
+        _fileSystemPaths = utils.copy(filePathsObject);
+        _fileSystemPaths.widgethome.uri = window.location.protocol + "//" + window.location.host + window.location.pathname;
+        db.saveObject(constants.FILESYSTEM.PERSISTENCE_KEY, filePathsObject);
+    },
+
+    override : function (from, to) {
+        _overrides[from] = to;
+    }
+};
+
+});
+require.define('ripple/deviceSettings', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* DeviceSettings
+ *  A per object store for a platform's settings.
+ *  For example, RadioInfo object in WAC has isRadioEnabled that can be true/false
+ *  setting => {key: {key1: "test"}}
+ */
+var _PERSISTENCE_KEY = "devicesettings",
+    db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    platform = require('ripple/platform'),
+    _currentDeviceSettings = {},
+    _self;
+
+function _default(key) {
+    var keys = key.split("."),
+        defaults = platform.current().device;
+    if (keys.length === 1)
+        return defaults[key];
+    return keys.length === 2 &&
+           defaults[keys[0]] &&
+           defaults[keys[0]][keys[1]] &&
+           defaults[keys[0]][keys[1]].control ?
+           defaults[keys[0]][keys[1]].control.value : undefined;
+}
+
+_self = {
+    initialize: function () {
+        // TODO: remove deprecated DeviceSettings from persisted ones.
+        _currentDeviceSettings = db.retrieveObject(_PERSISTENCE_KEY) || {};
+    },
+    register: function (key, obj) {
+        _currentDeviceSettings[key] = obj;
+    },
+
+    persist: function (key, obj) {
+        if (key) {
+            _currentDeviceSettings[key] = obj;
+        }
+
+        db.saveObject(_PERSISTENCE_KEY, _currentDeviceSettings);
+    },
+
+    retrieve: function (key) {
+        return _currentDeviceSettings.hasOwnProperty(key) ?
+               _currentDeviceSettings[key] : _default(key);
+    },
+
+    retrieveAsInt: function (key) {
+        return parseInt(_self.retrieve(key), 10);
+    },
+
+    retrieveAsBoolean: function (key) {
+        return !!_self.retrieve(key);
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/appcache', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    initialize: function () {
+        window.addEventListener('load', function (e) {
+            window.applicationCache.addEventListener('updateready', function (e) {
+                if (window.applicationCache.status === window.applicationCache.UPDATEREADY) {
+                    window.applicationCache.swapCache();
+                    window.location.reload();
+                }
+            }, false);
+        }, false);
+    }
+};
+
+});
+require.define('ripple/devices', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    platform = require('ripple/platform'),
+    constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    _devices = {};
+
+event.on("HardwareKeyDefault", function (key) {
+    if (key === 0 || key === "0") { //back button key
+        require('ripple/emulatorBridge').window().history.back();
+    }
+});
+
+function _currentID() {
+    var deviceID = db.retrieve(constants.DEVICE.SAVED_KEY),
+        currentDevice = _devices[deviceID] || null,
+        currentPlatformId = platform.current().id;
+
+    if (!currentDevice || !currentDevice.platforms.some(function (platformId) {
+            return platformId === currentPlatformId;
+        })) {
+        deviceID = utils.reduce(_devices, function (current, device, id) {
+            if (device.platforms.some(function (platformId) {
+                return platformId === currentPlatformId;
+            })) {
+                current = id;
+            }
+            return current;
+        });
+    }
+
+    return deviceID;
+}
+
+_self = module.exports = {
+    initialize: function () {
+        _devices = [
+/* 
+           "Bold9700",
+            "Bold9900",
+            "Curve9300",
+            "Curve9350-9360-9370",
+            "FWVGA",
+            "G1",
+*/
+            "HD",
+/*
+            "HPPre3",
+            "HPVeer",
+*/
+            "HVGA",
+/*
+            "iPad",
+            "iPhone3",
+            "Legend",
+            "Nexus",
+            "NexusS",
+            "NokiaN8",
+            "NokiaN97",
+            "PalmPre",
+            "PalmPre2",
+            "Pearl9100",
+            "Playbook",
+            "QVGA",
+            "Style9670",
+            "Tattoo",
+            "Torch9800",
+            "Torch9810",
+            "Torch9860-9850",
+            "Wave",
+            "WQVGA",
+*/
+            "WSVGA",
+            "WVGA"
+        ].reduce(function (hash, deviceID) {
+            hash[deviceID] = require('ripple/devices/' + deviceID);
+            return hash;
+        }, {});
+    },
+
+    getCurrentDevice: function () {
+        return this.getDevice(_currentID(),
+                              platform.current().id,
+                              platform.current().version);
+    },
+
+    getDevice: function (deviceId, platform, version) {
+        var device = _devices[deviceId] ? utils.copy(_devices[deviceId]) : null;
+
+        if (device && platform && version) {
+            if (device.overrides &&
+                device.overrides.api &&
+                device.overrides.api[platform]) {
+
+                utils.forEach(device.overrides.api[platform], function (override, index) {
+                    if (index !== "apiVersion") {
+                        device[index] = override;
+                    }
+                });
+
+                if (device.overrides.api[platform].apiVersion &&
+                    device.overrides.api[platform].apiVersion[version]) {
+
+                    utils.forEach(device.overrides.api[platform].apiVersion[version], function (override, index) {
+                        device[index] = override;
+                    });
+                }
+            }
+
+            delete device.overrides;
+        }
+
+        return device;
+    },
+
+    getDevicesForPlatform: function (platformId) {
+        //this doesn't do the overrides for the platform
+        //but it currently doesn't need to because
+        //this is just used for the list in the UI
+        // TODO: select devices based on both platform and version
+        return utils.filter(_devices, function (device) {
+            return device.platforms.indexOf(platformId) > -1;
+        });
+    }
+};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/audioPlayer', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//create my dom collection node in UI
+
+var utils = require('ripple/utils'),
+    constants = require('ripple/constants'),
+    notifications = require('ripple/notifications'),
+    Player = require('ripple/platform/webworks.handset/2.0.0/client/AudioPlayer'),
+    _handlers = {
+        loadstart: {},
+        canplaythrough: {},
+        durationchange: {},
+        ended: {},
+        error: {},
+        play: {},
+        pause: {},
+        volumechange: {},
+        close: {}
+    },
+    extract = {
+        time: function (audio) {
+            return audio.currentTime;
+        },
+        duration: function (audio) {
+            return audio.duration;
+        },
+        error: function (audio) {
+            return audio.error;
+        },
+        nothing: function (audio) {
+            return null;
+        }
+    },
+    container;
+
+container = utils.createElement("section", {
+    id: "webworks-audio-players"
+});
+
+document.getElementById("ui").appendChild(container);
+
+function _errClosed(method) {
+    notifications.openNotification("error",
+       "attempted to call " + method + " on a player that is already closed. This is a very bad thing to do :)");
+    return false;
+}
+
+function _removeHandler(type, id) {
+    var audio = document.getElementById(id);
+
+    if (audio && _handlers[type][id]) {
+        audio.removeEventListener(type, _handlers[type][id]);
+        delete _handlers[type][id];
+    }
+}
+
+function _addHandler(type, id, callback) {
+    var audio = document.getElementById(id);
+
+    if (audio) {
+        _removeHandler(type, id);
+        audio.addEventListener(type, callback);
+        _handlers[type][id] = callback;
+    }
+}
+
+function proxyEvent(from, map) {
+    var audio = document.getElementById(map.id);
+
+    if (audio) {
+        map.baton.take();
+        _addHandler(from, map.id, function () {
+            _removeHandler(from, map.id);
+            map.baton.pass({code: 1, data: {
+                event: map.target,
+                eventData: map.data(this)
+            }});
+        });
+    }
+    else {
+        return {code: -1, data: {event: "EVENT_ERROR", eventData: 5}};
+    }
+}
+
+module.exports = {
+
+    create: function (args) {
+        var id = Math.uuid(),
+            audio = utils.createElement("audio", {
+                id: id
+            });
+
+        audio.setAttribute("src", args.locator);
+
+        if (args.type) {
+            audio.setAttribute("type", args.type);
+        }
+
+        container.appendChild(audio);
+        audio.load();
+
+        if (audio.error) {
+            throw "there was a problem opening the audio file";
+        }
+
+        return {code: 1, data: id};
+    },
+
+    play: function (args) {
+        var audio = document.getElementById(args.id),
+            playing;
+
+        if (audio) {
+            audio.play();
+            audio.rimState = Player.STARTED;
+            playing = !!!audio.error;
+        }
+        else {
+            playing = _errClosed("play");
+        }
+
+        return {code: 1, data: playing};
+    },
+
+    pause: function (args) {
+        var audio = document.getElementById(args.id),
+            paused;
+
+        if (audio) {
+            audio.pause();
+            paused = !!!audio.error;
+        } else {
+            paused = _errClosed("pause");
+        }
+
+        return {code: 1, data: paused};
+    },
+
+    close: function (args) {
+        var audio = document.getElementById(args.id),
+            callback = _handlers["close"][args.id],
+            closed = true;
+
+        if (audio) {
+            if (callback) {
+                callback();
+            }
+            container.removeChild(audio);
+        }
+        else {
+            closed = _errClosed("close");
+        }
+
+        return {code: 1, data: closed};
+    },
+
+    onStart: function (args, post, baton) {
+        return proxyEvent("play", {
+            id: args.id,
+            baton: baton,
+            target: "EVENT_START",
+            data: extract.time
+        });
+    },
+
+    onStopped: function (args, post, baton) {
+        return proxyEvent("pause", {
+            id: args.id,
+            baton: baton,
+            target: "EVENT_STOPPED",
+            data: extract.time
+        });
+    },
+
+    onBufferingStarted: function (args, post, baton) {
+        return proxyEvent("loadstart", {
+            id: args.id,
+            baton: baton,
+            target: "EVENT_BUFFERING_STARTED",
+            data: extract.time
+        });
+    },
+
+    onBufferingStopped: function (args, post, baton) {
+        return proxyEvent("canplaythrough", {
+            id: args.id,
+            baton: baton,
+            target: "EVENT_BUFFERING_STOPPED",
+            data: extract.time
+        });
+    },
+
+    onDurationUpdated: function (args, post, baton) {
+        return proxyEvent("durationchange", {
+            id: args.id,
+            baton: baton,
+            target: "EVENT_DURATION_UPDATED",
+            data: extract.duration
+        });
+    },
+
+    onEnd: function (args, post, baton) {
+        return proxyEvent("ended", {
+            id: args.id,
+            baton: baton,
+            target: "EVENT_END_OF_MEDIA",
+            data: extract.duration
+        });
+    },
+
+    onError: function (args, post, baton) {
+        return proxyEvent("error", {
+            id: args.id,
+            baton: baton,
+            target: "EVENT_ERROR",
+            data: extract.error
+        });
+    },
+
+    onVolumeChange: function (args, post, baton) {
+        return proxyEvent("volumechange", {
+            id: args.id,
+            baton: baton,
+            target: "EVENT_VOLUME_CHANGED",
+            data: extract.nothing
+        });
+    },
+
+    onClose: function (args, post, baton) {
+        return proxyEvent("close", {
+            id: args.id,
+            baton: baton,
+            target: "EVENT_CLOSED",
+            data: extract.nothing
+        });
+    },
+
+    getDuration: function (args) {
+        var audio = document.getElementById(args.id),
+            duration;
+
+        if (audio) {
+            duration = audio.duration;
+        }
+        else {
+            _errClosed("getDuration");
+            duration = -1;
+        }
+
+        return {code: 1, data: duration};
+    },
+
+    getMediaTime: function (args) {
+        var audio = document.getElementById(args.id),
+            time;
+
+        if (audio) {
+            time = audio.currentTime;
+        }
+        else {
+            _errClosed("getMediaTime");
+            time = -1;
+        }
+
+        return {code: 1, data: time};
+    },
+
+    setMediaTime: function (args) {
+        var audio = document.getElementById(args.id);
+
+        if (audio) {
+            audio.currentTime = args.value;
+        }
+        else {
+            _errClosed("setMediaTime");
+        }
+
+        return {code: 1};
+    },
+
+    getVolumeLevel: function (args) {
+        var audio = document.getElementById(args.id),
+            level;
+
+        if (audio) {
+            level = audio.volume * 100;
+        }
+        else {
+            _errClosed("getVolumeLevel");
+            level = -1;
+        }
+
+        return {code: 1, data: level};
+    },
+
+    setVolumeLevel: function (args) {
+        var audio = document.getElementById(args.id);
+
+        if (audio) {
+            audio.volume = args.value / 100;
+        }
+        else {
+            _errClosed("setVolumeLevel");
+        }
+
+        return {code: 1};
+    },
+
+    getState: function (args) {
+        var audio = document.getElementById(args.id),
+            state = audio ? audio.rimState || Player.PREFETCHED : Player.CLOSED;
+        return {code: 1, data: state};
+    }
+};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/dialog', function (require, module, exports) {
+module.exports = {};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/appEvent', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    _bg,
+    _fg,
+    _exit;
+
+event.on("AppRequestBackground", function () {
+    var baton = _bg;
+    _bg = null;
+    return baton && baton.pass({code: 1});
+});
+
+event.on("AppRequestForeground", function () {
+    var baton = _fg;
+    _fg = null;
+    return baton && baton.pass({code: 1});
+});
+
+event.on("AppExit", function () {
+    var baton = _exit;
+    _exit = null;
+    return baton && baton.pass({code: 1});
+});
+
+module.exports = {
+    onBackground: function (get, post, baton) {
+        baton.take();
+        _bg = baton;
+        return {code: 1};
+    },
+
+    onForeground: function (get, post, baton) {
+        baton.take();
+        _fg = baton;
+        return {code: 1};
+    },
+
+    onExit: function (get, post, baton) {
+        baton.take();
+        _exit = baton;
+        return {code: 1};
+    }
+};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/phone', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var PhoneCall = require('ripple/platform/webworks.handset/2.0.0/client/PhoneCall'),
+    PhoneLogs = require('ripple/platform/webworks.handset/2.0.0/client/PhoneLogs'),
+    CallLog = require('ripple/platform/webworks.handset/2.0.0/client/CallLog'),
+    select = require('ripple/platform/webworks.core/2.0.0/select'),
+    event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    _KEY = "blackberry-phone-logs",
+    _onPhoneEventListeners = {},
+    _activeCalls = {},
+    _onCallLogAdded,
+    _onCallLogRemoved,
+    _onCallLogUpdated,
+    _onCallLogReset,
+    _self;
+
+function _defaultLogs() {
+    var n1 = new CallLog(),
+        n2 = new CallLog(),
+        m1 = new CallLog(),
+        m2 = new CallLog();
+
+    n1.number = "12344567";
+    n1.name = "larry";
+    n1.type = CallLog.TYPE_PLACED_CALL;
+    n1.status = CallLog.STATUS_NORMAL;
+
+    n2.number = "14567890";
+    n2.name = "curly";
+    n2.type = CallLog.TYPE_RECEIVED_CALL;
+    n2.status = CallLog.STATUS_NORMAL;
+
+    m1.number = "17659800";
+    m1.name = "moe";
+    m1.type = CallLog.TYPE_MISSED_CALL_UNOPENED;
+    m1.status = CallLog.STATUS_NORMAL;
+
+    m2.number = "14567896";
+    m2.name = "snarf";
+    m2.type = CallLog.TYPE_MISSED_CALL_OPENED;
+    m2.status = CallLog.STATUS_NORMAL;
+
+    return {
+        normal: [n1, n2],
+        missed: [m1, m2]
+    };
+}
+
+function _getLogs(folderID) {
+    var logs = db.retrieveObject(_KEY) || _defaultLogs();
+    return folderID === undefined || folderID === null ?
+        logs : logs[folderID !== PhoneLogs.FOLDER_NORMAL_CALLS ? "missed" : "normal"];
+}
+
+function _saveLogs(logs) {
+    db.saveObject(_KEY, logs);
+}
+
+function _isMissedCall(log) {
+    return (log.type === CallLog.TYPE_MISSED_CALL_UNOPENED ||
+            log.type === CallLog.TYPE_MISSED_CALL_OPENED) ? true : false;
+}
+
+function _isNormalCall(log) {
+    return (log.type === CallLog.TYPE_RECEIVED_CALL ||
+            log.type === CallLog.TYPE_PLACED_CALL) ? true : false;
+}
+
+event.on("PhoneEvent", function (type, callId, error) {
+    var baton = _onPhoneEventListeners[type];
+    delete _onPhoneEventListeners[type];
+
+    return baton && baton.pass({code: 1, data: {callId: callId, error: error}});
+});
+
+event.on("PhoneCallLogAdded", function (log) {
+    var logs = _getLogs(),
+        baton = _onCallLogAdded;
+
+    logs[_isMissedCall(log) ? "missed" : "normal"].push(log);
+    _saveLogs(logs);
+
+    _onCallLogAdded = null;
+    return baton && baton.pass({code: 1, data: {log: log}});
+});
+
+event.on("PhoneCallLogRemoved", function (log) {
+    // TODO: make this be the only one responsible for deletion (instead of triggering internally)
+    var baton = _onCallLogRemoved;
+    _onCallLogRemoved = null;
+    return baton && baton.pass({code: 1, data: {log: log}});
+});
+
+event.on("PhoneCallLogUpdated", function (newLog, oldLog) {
+    // TODO: implement way to update with just this event
+    var baton = _onCallLogUpdated;
+    _onCallLogUpdated = null;
+    return baton && baton.pass({code: 1, data: {
+        newLog: newLog,
+        oldLog: oldLog
+    }});
+});
+
+event.on("PhoneCallLogReset", function () {
+    _saveLogs(_defaultLogs());
+    var baton = _onCallLogReset;
+    _onCallLogReset = null;
+    return baton && baton.pass({code: 1});
+});
+
+event.on("PhoneCallInitiated", function (call) {
+    _activeCalls[call.id] = call;
+});
+
+event.on("PhoneCallEnded", function (call) {
+    delete _activeCalls[call.id];
+});
+
+_self = {
+    logs: {
+        onCallLogAdded: function (get, post, baton) {
+            baton.take();
+            _onCallLogAdded = baton;
+        },
+
+        onCallLogRemoved: function (get, post, baton) {
+            baton.take();
+            _onCallLogRemoved = baton;
+        },
+
+        onCallLogUpdated: function (get, post, baton) {
+            baton.take();
+            _onCallLogUpdated = baton;
+        },
+
+        onCallLogReset: function (get, post, baton) {
+            baton.take();
+            _onCallLogReset = baton;
+        },
+
+        callAt: function (get) {
+            var logs = _getLogs(get.folderID !== null && get.folderID !== undefined ?
+                                        get.folderID : PhoneLogs.FOLDER_MISSED_CALLS);
+            return {code: 1, data: logs.length > get.index ? logs[get.index] : null};
+        },
+
+        deleteCallAt: function (get) {
+            var logs = _getLogs(),
+                subLog = _getLogs(get.folderID),
+                deleted = false,
+                type, log;
+
+            if (subLog.length > get.index &&
+               (type = _isNormalCall(subLog[get.index]) ? "normal" : "missed") &&
+               (log = logs[type].splice(get.index, 1))) {
+                event.trigger("PhoneCallLogRemoved", [log]);
+                _saveLogs(logs);
+                deleted = true;
+            }
+
+            return {code: 1, data: deleted};
+        },
+
+        find: function (get, post) {
+            var data = select.from(_getLogs(post.folderID !== null && post.folderID !== undefined ?
+                                        post.folderID : PhoneLogs.FOLDER_MISSED_CALLS))
+                    .orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc")
+                    .max(post.maxReturn)
+                    .where(post.filter, select.ops.phone);
+            return {code: 1, data: data};
+        },
+
+        numberOfCalls: function (get) {
+            return {code: 1, data: _getLogs(get.folderID !== null && get.folderID !== undefined ?
+                                        get.folderID : PhoneLogs.FOLDER_MISSED_CALLS).length};
+        }
+    },
+
+    onPhoneEvent: function (get, post, baton) {
+        baton.take();
+        _onPhoneEventListeners[get.eventType] = baton;
+    },
+
+    activeCalls: function () {
+        var data = utils.map(_activeCalls, function (callItem) {
+            var call = new PhoneCall(callItem.onhold);
+            call.outgoing = callItem.outgoing;
+            call.recipientName = callItem.recipient.name;
+            call.recipientNumber = callItem.recipient.number;
+            return call;
+        });
+        return {code: 1, data: data};
+    },
+
+    inActiveCall: function () {
+        return {code: 1, data: utils.count(_activeCalls) > 0 ? true : false};
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/app', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    app = require('ripple/app'),
+    notifications = require('ripple/notifications'),
+    constants = require('ripple/constants'),
+    ui = require('ripple/ui'),
+    _isForeground = true,
+    _self;
+
+_self = {
+    event: require('ripple/platform/webworks.handset/2.0.0/server/appEvent'),
+
+    exit: function () {
+        event.trigger("AppExit");
+        return {code: 1};
+    },
+
+    author: function () {
+        return {code: 1, data: app.getInfo().author};
+    },
+
+    authorEmail: function () {
+        return {code: 1, data: app.getInfo().authorEmail};
+    },
+
+    authorURL: function () {
+        return {code: 1, data: app.getInfo().authorURL};
+    },
+
+    copyright: function () {
+        return {code: 1, data: app.getInfo().copyright};
+    },
+
+    description: function () {
+        return {code: 1, data: app.getInfo().description};
+    },
+
+    isForeground: function () {
+        return {code: 1, data: _isForeground};
+    },
+
+    id: function () {
+        return {code: 1, data: app.getInfo().id};
+    },
+
+    license: function () {
+        return {code: 1, data: app.getInfo().license};
+    },
+
+    licenseURL: function () {
+        return {code: 1, data: app.getInfo().licenseURL};
+    },
+
+    name: function () {
+        return {code: 1, data: app.getInfo().name};
+    },
+
+    version: function () {
+        return {code: 1, data: app.getInfo().version};
+    },
+
+    requestBackground: function () {
+        ui.showOverlay("background-window", function (background) {
+            var button = background.children["background-return"];
+
+            if (button) {
+                button.addEventListener("click", _self.requestForeground);
+            }
+            _isForeground = false;
+            event.trigger("AppRequestBackground");
+        });
+
+        return {code: 1};
+    },
+
+    requestForeground: function () {
+        ui.hideOverlay("background-window", function (background) {
+            var button = background.children["background-return"];
+
+            if (button) {
+                button.removeEventListener("click", _self.requestForeground);
+            }
+            _isForeground = true;
+            event.trigger("AppRequestForeground");
+        });
+
+        return {code: 1};
+    },
+
+    setHomeScreenIcon: function (args) {
+        if (args.uri) {
+            var msg = "The application set the home screen" +
+               (args.hover ? " hover " : " ") +
+               "icon to " + args.uri;
+
+            notifications.openNotification("normal", msg);
+            return {code: 1};
+        }
+        else {
+            return {code: 0};
+        }
+    },
+
+    setHomeScreenName: function (args) {
+        if (args.text) {
+            var msg = "The application set the home screen name to " + args.text;
+            notifications.openNotification("normal", msg);
+            return {code: 1};
+        }
+        else {
+            return {code: 1};
+        }
+    },
+
+    removeBannerIndicator: function () {
+        event.trigger("BannerUpdated", ["", 0]);
+        return {code: 1};
+    },
+
+    showBannerIndicator: function (args) {
+        event.trigger("BannerUpdated", [args.icon, args.count]);
+        return {code: 1};
+    },
+
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/sms', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _listener,
+    _isListening = false,
+    notifications = require('ripple/notifications'),
+    constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    _console = require('ripple/console'),
+    _onReceive,
+    _self;
+
+event.on("MessageReceived", function (message) {
+    if (!_isListening || message.type !== 'sms') {
+        return;
+    }
+
+    var baton = _onReceive;
+    _onReceive = null;
+    _isListening = false;
+    return baton && baton.pass({code: 1, data: message});
+});
+
+_self = {
+    onReceive: function (args, post, baton) {
+        baton.take();
+        _onReceive = baton;
+        _isListening = !!_onReceive;
+    },
+
+    send: function (args) {
+        var msg = "To " + args.address + ": " + args.message;
+        notifications.openNotification("normal", msg);
+        _console.log(msg);
+        return {code: 1};
+    },
+
+    isListeningForMessage: function (get, post, baton) {
+        if (get && typeof get.isListeningForMessage === "boolean") {
+            _isListening = get.isListeningForMessage;
+        }
+
+        return {code: 1, data: _isListening};
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/message', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    select = require('ripple/platform/webworks.core/2.0.0/select'),
+    Message = require('ripple/platform/webworks.handset/2.0.0/client/Message'),
+    _self;
+
+function _get() {
+    return db.retrieveObject("webworks-message-list") || {};
+}
+
+function _do(func) {
+    var messages = _get();
+    func(messages);
+    db.saveObject("webworks-message-list", messages);
+}
+
+_self = {
+    find: function (get, post) {
+        var data = select
+                .from(_get())
+                .max(post.maxReturn)
+                .where(post.filter);
+        return {code: 1, data: data};
+    },
+
+    remove: function (get, post) {
+        _do(function (messages) {
+            if (!messages[get.uid]) {
+                throw "attempting to delete a non existant message with uid: " + get.uid;
+            }
+            delete messages[get.uid];
+        });
+        return {code: 1};
+    },
+
+    save: function (get, post) {
+        _do(function (messages) {
+            var orig = messages[post.message.uid],
+                updated = utils.copy(post.message);
+
+            updated.folder = orig ? orig.folder : Message.FOLDER_DRAFT;
+            updated.status = orig ? orig.status : Message.STATUS_DRAFT;
+
+            messages[post.message.uid] = updated;
+        });
+        return {code: 1};
+    },
+
+    send: function (get, post) {
+        _do(function (messages) {
+            var updated = utils.copy(get.message);
+
+            updated.folder = Message.FOLDER_SENT;
+            updated.status = Message.STATUS_SENT;
+
+            messages[updated.uid] = updated;
+        });
+        return {code: 1};
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/io/dir', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var cache = require('ripple/platform/webworks.core/2.0.0/fsCache'),
+    dir = require('ripple/platform/webworks.core/2.0.0/server/io/dir'),
+    utils = require('ripple/utils'),
+    _self = {};
+
+function _packet(data) {
+    return {
+        code: 1,
+        data: data
+    };
+}
+
+utils.mixin({
+    getFreeSpaceForRoot: function (get, post, baton) {
+        return _packet(cache.dir.getFreeSpaceForRoot(post.path));
+    },
+    getRootDirs: function (get, post, baton) {
+        return _packet(cache.dir.getRootDirs());
+    }
+}, _self);
+
+utils.mixin(dir, _self);
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/push', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    _handlers = {},
+    _self;
+
+function listenersChanged() {
+    var ports = utils.map(_handlers, function (handler) {
+        return handler.port;
+    });
+    event.trigger("PushListenersChanged", [ports]);
+}
+
+event.on("Push", function (data, port) {
+    var handler = _handlers["port_" + port];
+    delete _handlers["port_" + port];
+    window.setTimeout(function () {
+        if (!_handlers["port_" + port]) {
+            //doesn't look like they are coming back ;)
+            listenersChanged();
+        }
+    }, 100);
+    return handler && handler.baton.pass({code: 1, data: data});
+});
+
+_self = {
+
+    onPush: function (args, post, baton) {
+        if (!args.port) {
+            throw "no port specified";
+        }
+        else if (typeof args.port !== 'number') {
+            throw "port is not a number";
+        }
+        baton.take();
+        _handlers["port_" + args.port] = {
+            port: args.port,
+            baton: baton
+        };
+        listenersChanged();
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/invoke', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var notifications = require('ripple/notifications'),
+    constants = require('ripple/constants'),
+    type = "normal",
+    name = {
+        "0": "Address Book",
+        "1": "Bluetooth Config",
+        "2": "Calculator",
+        "3": "Calendar",
+        "camera://": "Camera",
+        "camera://video": "Video Camera",
+        "map://": "Maps",
+        "6": "Memopad",
+        "7": "Messages",
+        "8": "Phone",
+        "9": "Search",
+        "10": "Tasks",
+        "11": "Browser",
+        "http://": "Browser",
+        "12": "Java",
+    };
+
+module.exports = {
+    invoke: function (opts) {
+        var app = name[opts.appType];
+        if (app === undefined && opts.appType && opts.appType.match(/^http/i)) {
+            app = "Browser";
+        }
+
+        notifications.openNotification(type,
+           "Requested to launch: " + app + " application.");
+        return {code: 1};
+    }
+};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/contact', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var select = require('ripple/platform/webworks.core/2.0.0/select'),
+    db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    _KEY = "blackberry-pim-contacts",
+    _self;
+
+function _defaultContacts() {
+    var id1 = Math.uuid(null, 16),
+        id2 = Math.uuid(null, 16),
+        id3 = Math.uuid(null, 16),
+        id4 = Math.uuid(null, 16),
+        contacts = {};
+
+    contacts[id1] = {
+        uuid: id1,
+        firstName: "Leonardo",
+        homePhone: "4567892345",
+        email1: "leo@underground.com"
+    };
+    contacts[id2] = {
+        uuid: id2,
+        firstName: "Raphael",
+        homePhone: "4563457890",
+        email1: "raph@underground.com"
+    };
+    contacts[id3] = {
+        uuid: id3,
+        firstName: "Michelangelo",
+        homePhone: "4563453425",
+        email1: "mike@underground.com"
+    };
+    contacts[id4] = {
+        uuid: id4,
+        firstName: "Donatello",
+        homePhone: "4563453425",
+        email1: "don@undergound.com"
+    };
+
+    return contacts;
+}
+
+function _get() {
+    return db.retrieveObject(_KEY) || _defaultContacts();
+}
+
+function _save(contacts) {
+    db.saveObject(_KEY, contacts);
+}
+
+//---------------------------------------------------
+//HACK: gotta fix the shiznit
+//TODO: if still here at 0.7.0 please remove
+var fix = _get();
+if (fix instanceof Array) {
+    _save(_defaultContacts());
+}
+//END OF HACK (may god have mercy on our souls)
+//---------------------------------------------------
+
+_self = {
+    save: function (get, post) {
+        var contacts = _get();
+
+        contacts[post.contact.uid] = post.contact;
+        _save(contacts);
+        return {code: 1};
+    },
+    remove: function (get, post) {
+        var contacts = _get(),
+            id = get.id;
+
+        delete contacts[id];
+        _save(contacts);
+        return {code: 1};
+    },
+    find: function (get, post) {
+        var contacts = _get(),
+            match = select.from(contacts);
+
+        if (post.orderBy) {
+            match.orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc");
+        }
+
+        if (post.maxReturn) {
+            match.max(post.maxReturn);
+        }
+
+        return {code: 1, data: match.where(post.fieldFilter)};
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/Task', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var select = require('ripple/platform/webworks.core/2.0.0/select'),
+    db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    _KEY = "blackberry-pim-task",
+    _self;
+
+function _get() {
+    return db.retrieveObject(_KEY) || {};
+}
+
+function _save(tasks) {
+    db.saveObject(_KEY, tasks);
+}
+
+_self = {
+    save: function (get, post) {
+        var tasks = _get(),
+            properties = post.task,
+            id = properties.uid;
+
+        if (tasks[id]) {
+            utils.mixin(properties, tasks[id]);
+        } else {
+            tasks[id] = properties;
+        }
+
+        _save(tasks);
+
+        return {code: 1};
+    },
+
+    remove: function (get, post) {
+        var tasks = _get(),
+            id = get.id;
+
+        delete tasks[id];
+
+        _save(tasks);
+
+        return {code: 1};
+    },
+
+    find: function (get, post) {
+        var tasks = _get(),
+            match = select.from(tasks);
+
+        if (post.orderBy) {
+            match.orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc");
+        }
+
+        if (post.maxReturn) {
+            match.max(post.maxReturn);
+        }
+
+        return {code: 1, data: match.where(post.filter)};
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/appointment', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var db = require('ripple/db'),
+    select = require('ripple/platform/webworks.core/2.0.0/select'),
+    _self;
+
+function _get() {
+    return db.retrieveObject("webworks-pim-appointment-list") || {};
+}
+
+function _do(func) {
+    var appointments = _get();
+    func(appointments);
+    db.saveObject("webworks-pim-appointment-list", appointments);
+}
+
+_self = {
+    find: function (get, post) {
+        var appointments = _get(),
+            data = select.from(appointments)
+                    .orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc")
+                    .max(post.maxReturn)
+                    .where(post.filter);
+
+        return {code: 1, data: data};
+    },
+
+    remove: function (get) {
+        _do(function (appointments) {
+            if (!appointments[get.uid]) {
+                throw "attempting to delete a non existant appointment with uid: " + get.uid;
+            }
+            delete appointments[get.uid];
+        });
+
+        return {code: 1};
+    },
+
+    save: function (get, post) {
+        _do(function (appointments) {
+            appointments[post.appointment.uid] = post.appointment;
+        });
+
+        return {code: 1};
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/menu', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _menuItems = {},
+    constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    events = require('ripple/platform/webworks.core/2.0.0/client/events'),
+    ui = require('ripple/ui'),
+    devices = require('ripple/devices'),
+    utils = require('ripple/utils'),
+    tooltip = require('ripple/ui/plugins/tooltip'),
+    _self,
+    isMenuOpen = false,
+    _baton,
+    menuWindow = document ? document.getElementById("menu-window") : undefined;
+
+if (menuWindow) {
+    menuWindow.addEventListener("click", function () {
+        _self.close();
+    });
+}
+
+event.on("LayoutChanged", function () {
+    if (isMenuOpen) {
+        _self.close();
+        //Used to resize menu on orientation change
+        _self.open();
+    }
+});
+
+event.on("HardwareKeyDefault", function (key) {
+    if (key === 1 || key === "1") { //menu button key
+        if (isMenuOpen) {
+            _self.close();
+        }
+        else {
+            _self.open();
+        }
+    }
+});
+
+event.on("MenuItemSelected", function (menuItem) {
+    var baton = _baton;
+    _baton = null;
+    return baton && baton.pass({code: 1, data: menuItem});
+});
+
+event.on("MenuItemChanged", function (menuItem) {
+    _menuItems[menuItem.id] = menuItem;
+});
+
+_self = {
+
+    onSelect : function (args, post, baton) {
+        baton.take();
+        _baton = baton;
+    },
+
+    addMenuItem: function (args) {
+        if (!args) {
+            throw "item not found";
+        }
+        _menuItems[args.item.id] = args.item;
+        event.trigger("MenuChanged", [_menuItems]);
+        return {code: 1};
+    },
+
+    clearMenuItems: function () {
+        _menuItems = {};
+        event.trigger("MenuChanged", [utils.copy(_menuItems)]);
+        return {code: 1};
+    },
+
+    open: function () {
+        function _return() {
+            return {code: 1};
+        }
+
+        if (utils.count(_menuItems) === 0) {
+            _return();
+        }
+
+        ui.showOverlay("menu-window", function (menu) {
+            var container = document.getElementById(constants.COMMON.VIEWPORT_CONTAINER),
+                height = window.getComputedStyle(container, null).getPropertyValue("height"),
+                width = window.getComputedStyle(container, null).getPropertyValue("width"),
+                menuButtons = document.getElementById("menu-buttons"),
+                sorted,
+                menuItem;
+
+            if (!menuButtons) {
+                _return();
+            }
+
+            menu.setAttribute("style", "display:block;height:" + height + "; width:" + width + ";");
+            isMenuOpen = true;
+
+            sorted = utils.map(_menuItems, function (item) {
+                return item;
+            }).sort(function (a, b) {
+                return a.ordinal - b.ordinal;
+            });
+
+            menuButtons.innerHTML = "";
+            sorted.forEach(function (item) {
+                if (!item.isSeparator) {
+                    if (item.isDefault) {
+                        menuItem = utils.createElement("div", {
+                            "class": "overlay-menu-item-default",
+                            "id": "default-menu-item"
+                        });
+                    }
+                    else {
+                        menuItem = utils.createElement("div", {
+                            "class": "overlay-menu-item"
+                        });
+                    }
+                    menuItem.innerHTML = item.caption;
+
+                    menuItem.addEventListener("click", function () {
+                        _baton.pass({code: 1, data: item.id});
+                    });
+                }
+                else {
+                    menuItem = utils.createElement("hr", {});
+                }
+                menuButtons.appendChild(menuItem);
+                tooltip.create("#default-menu-item", "Default Item");
+            });
+        }, true);
+
+        event.trigger("MenuOpened", []);
+
+        _return();
+    },
+
+    close: function () {
+        ui.hideOverlay("menu-window", function (menu) {
+            var menuButtons = document.getElementById("menu-buttons");
+            menuButtons.innerHTML = "";
+            isMenuOpen = false;
+            menu.setAttribute("style", "display:none;");
+
+        });
+        return {code: 1};
+    },
+
+    removeMenuItem: function (args) {
+        delete _menuItems[args.item.id];
+        event.trigger("MenuChanged", [_menuItems]);
+        return {code: 1};
+    },
+
+    setDefaultMenuItem: function (args) {
+
+        utils.forEach(_menuItems, function (item) {
+            item.isDefault = false;
+        });
+
+        _menuItems[args.id].isDefault = true;
+
+        event.trigger("DefaultItemChanged", [_menuItems[args.id]]);
+        return {code: 1};
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/identity', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    Service = require('ripple/platform/webworks.handset/2.0.0/client/identity/Service'),
+    Transport = require('ripple/platform/webworks.handset/2.0.0/client/identity/Transport'),
+    utils = require('ripple/utils'),
+    platform = require('ripple/platform'),
+    deviceSettings = require('ripple/deviceSettings'),
+    _transportTypes = [
+        {name: "TCP Cellular", type: "TCP Cellular"},
+        {name: "Wap", type: "Wap"},
+        {name: "Wap 2.0", type: "Wap 2.0"},
+        {name: "MDS", type: "MDS"},
+        {name: "BIS B", type: "Bis B"},
+        {name: "Unite!", type: "Unite!"},
+        {name: "TCP Wifi", type: "TCP Wifi"},
+    ],
+    _services = [
+        new Service(),
+        new Service()
+    ];
+
+function _isTransportAvailable(transport) {
+    return deviceSettings.retrieveAsBoolean("transports." + transport.type);
+}
+
+utils.mixin({
+    name: "Super Dave Osborne",
+    emailAddress: "dave@stunt.com",
+    isDefault: true,
+    type: Service.TYPE_EMAIL
+}, _services[0]);
+
+utils.mixin({
+    name: "Fred Penner",
+    emailAddress: "fred@fredpenner.com",
+    isDefault: false,
+    type: Service.TYPE_CONTACT
+}, _services[1]);
+
+_self = {
+    getDefaultService: function () {
+        var serices = _services.filter(function (service) {
+            return service.isDefault === true;
+        });
+        return {code: 1, data: serices};
+    },
+    getServiceList: function () {
+        return {code: 1, data: _services};
+    },
+    getTransportList: function () {
+        var transports = _transportTypes.filter(function (transport) {
+            return _isTransportAvailable(transport);
+        }).map(function (transport) {
+            return new Transport(transport.name, transport.type);
+        });
+        return {code: 1, data: transports};
+    },
+    IMEI: function () {
+        return {code: 1, data: deviceSettings.retrieve("identity.IMEI")};
+    },
+    IMSI: function () {
+        return {code: 1, data: deviceSettings.retrieve("identity.IMSI")};
+    },
+    PIN: function () {
+        return {code: 1, data: deviceSettings.retrieve("identity.PIN")};
+    },
+    phone: require('ripple/platform/webworks.handset/2.0.0/server/identity/phone')
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/memo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var db = require('ripple/db'),
+    select = require('ripple/platform/webworks.core/2.0.0/select'),
+    _self;
+
+function _get() {
+    return db.retrieveObject("webworks-pim-memo-list") || {};
+}
+
+function _do(func) {
+    var memos = _get();
+    func(memos);
+    db.saveObject("webworks-pim-memo-list", memos);
+}
+
+_self = {
+    find: function (get, post) {
+        var memos = select.from(_get())
+                    .orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc")
+                    .max(post.maxReturn)
+                    .where(post.filter);
+        return {code: 1, data: memos};
+    },
+    remove: function (get, post) {
+        _do(function (memos) {
+            if (!memos[get.uid]) {
+                throw "attempting to delete a non existant memo with uid: " + get.uid;
+            }
+            delete memos[get.uid];
+        });
+        return {code: 1};
+    },
+    save: function (get, post) {
+        _do(function (memos) {
+            memos[post.memo.uid] = post.memo;
+        });
+        return {code: 1};
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/identity/phone', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _lines = [
+        {id: 1, number: 12345678910, label: "rogers", type: 1},
+        {id: 2, number: 10987654321, label: "mystery", type: 0}
+    ],
+    _self;
+
+function _filterLines(args) {
+
+    var result = _lines;
+
+    if (args && typeof args.id === "number") {
+        result = _lines.filter(function (line) {
+            return line.id === args.id;
+        });
+
+        if (result.length === 0) {
+            throw "invalid line id: " + args.id;
+        }
+    }
+
+    return result;
+}
+
+_self = {
+    getLineIds: function () {
+        var lines = _lines.map(function (line) {
+            return line.id;
+        });
+        return {
+            code: 1,
+            data: lines
+        };
+    },
+    getLineLabel: function (args) {
+        return {
+            code: 1,
+            data: _filterLines(args)[0].label
+        };
+    },
+    getLineNumber: function (args) {
+        return {
+            code: 1,
+            data: _filterLines(args)[0].number
+        };
+    },
+    getLineType: function (args) {
+        return {
+            code: 1,
+            data: _filterLines(args)[0].type
+        };
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/systemEvent', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    _onCoverageChange,
+    _onHardwareKey = {};
+
+event.on("CoverageChange", function () {
+    var baton = _onCoverageChange;
+    _onCoverageChange = null;
+    return baton && baton.pass({code: 1});
+});
+
+event.on("HardwareKey", function (key) {
+    var baton = _onHardwareKey["key_" + key];
+    delete _onHardwareKey["key_" + key];
+
+    if (baton) {
+        baton.pass({code: 1});
+    }
+    else {
+        event.trigger("HardwareKeyDefault", [key]);
+    }
+});
+
+module.exports = {
+    onCoverageChange: function (args, post, baton) {
+        baton.take();
+        _onCoverageChange = baton;
+    },
+
+    onHardwareKey: function (args, post, baton) {
+        baton.take();
+        _onHardwareKey["key_" + args.key] = baton;
+    }
+};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server/category', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var db = require('ripple/db'),
+    _KEY = "blackberry-pim-category",
+    _self;
+
+function _get() {
+    return db.retrieveObject(_KEY) || [];
+}
+
+function _save(category) {
+    var categories = _get();
+    if (!categories.some(function (item) {
+        return item === category;
+    })) {
+        categories.push(category);
+        db.saveObject(_KEY, categories);
+    }
+}
+
+function _remove(category) {
+    var categories = _get(),
+        index = categories.indexOf(category);
+
+    if (index >= 0) {
+        categories.splice(index, 1);
+        db.saveObject(_KEY, categories);
+    }
+}
+
+_self = {
+    addCategory: function (args) {
+        _save(args.categoryName);
+        return {code: 1};
+    },
+    deleteCategory: function (args) {
+        _remove(args.categoryName);
+        return {code: 1};
+    },
+    getCategories: function () {
+        return {code: 1, data: _get()};
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/server', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    platform = "ripple/platform/webworks.handset/2.0.0/server/",
+    core = "ripple/platform/webworks.core/2.0.0/server/",
+    systemEvent = require(platform + 'systemEvent'),
+    system = {};
+
+// ugh, thanks to the spec...
+system.event = systemEvent;
+utils.mixin(require(core + "system"), system);
+
+module.exports = {
+    blackberry: {
+        invoke: require(platform + "invoke"),
+        system: system,
+        app: require(platform + "app"),
+        identity: require(platform + "identity"),
+        message: {
+            sms: require(platform + "sms"),
+            message: require(platform + "message")
+        },
+        push: require(platform + "push"),
+        pim: {
+            Task: require(platform + "Task"),
+            category: require(platform + "category"),
+            memo: require(platform + "memo"),
+            appointment: require(platform + "appointment"),
+            contact: require(platform + "contact")
+        },
+        audio: {
+            player: require(platform + "audioPlayer")
+        },
+        ui: {
+            menu: require(platform + "menu"),
+            dialog: require(platform + "dialog")
+        },
+        phone: require(platform + "phone"),
+        io: {
+            dir: require(platform + "io/dir"),
+            file: require(core + "io/file")
+        }
+    }
+};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/XMLHttpRequest', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var xhr = require("ripple/platform/webworks.core/2.0.0/XMLHttpRequest");
+module.exports = xhr.create("ripple/platform/webworks.handset/2.0.0/server");
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/CallLog', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function CallLog() {
+    // readwrite  property  String   addressBookNumber
+    // readwrite  property  String   addressBookType
+    // readwrite  property  Date   date
+    // readwrite  property  Number   duration
+    // readwrite  property  String   name
+    // readwrite  property  String   notes
+    // readwrite  property  String   number
+    // readwrite  property  Number   status
+    // readwrite  property  Number   type
+    this.addressBookNumber = null;
+    this.addressBookType = null;
+    this.date = null;
+    this.duration = null;
+    this.name = null;
+    this.notes = null;
+    this.number = null;
+    this.status = null;
+    this.type = null;
+}
+
+function _get(val) {
+    return function () {
+        return val;
+    };
+}
+
+CallLog.__defineGetter__("STATUS_NORMAL", _get(0));
+CallLog.__defineGetter__("STATUS_BUSY", _get(1));
+CallLog.__defineGetter__("STATUS_CONGESTION", _get(2));
+CallLog.__defineGetter__("STATUS_PATH_UNAVAILABLE", _get(3));
+CallLog.__defineGetter__("STATUS_NUMBER_UNOBTAINABLE", _get(4));
+CallLog.__defineGetter__("STATUS_AUTHENTICATION_FAILURE", _get(5));
+CallLog.__defineGetter__("STATUS_EMERGENCY_CALLS_ONLY", _get(6));
+CallLog.__defineGetter__("STATUS_HOLD_ERROR", _get(7));
+CallLog.__defineGetter__("STATUS_OUTGOING_CALLS_BARRED", _get(8));
+CallLog.__defineGetter__("STATUS_GENERAL_ERROR", _get(9));
+CallLog.__defineGetter__("STATUS_MAINTENANCE_REQUIRED", _get(10));
+CallLog.__defineGetter__("STATUS_SERVICE_NOT_AVAILABLE", _get(11));
+CallLog.__defineGetter__("STATUS_CALL_FAIL_DUE_TO_FADING", _get(12));
+CallLog.__defineGetter__("STATUS_CALL_LOST_DUE_TO_FADING", _get(13));
+CallLog.__defineGetter__("STATUS_CALL_FAILED_TRY_AGAIN", _get(14));
+CallLog.__defineGetter__("STATUS_FDN_MISMATCH", _get(15));
+CallLog.__defineGetter__("STATUS_CONNECTION_DENIED", _get(16));
+CallLog.__defineGetter__("STATUS_INCOMING_CALL_BARRED", _get(17));
+CallLog.__defineGetter__("TYPE_RECEIVED_CALL", _get(0));
+CallLog.__defineGetter__("TYPE_PLACED_CALL", _get(1));
+CallLog.__defineGetter__("TYPE_MISSED_CALL_UNOPENED", _get(2));
+CallLog.__defineGetter__("TYPE_MISSED_CALL_OPENED", _get(3));
+
+module.exports = CallLog;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/AddressBookArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.AddressBookArguments ( [contact : blackberry.pim.Contact ] )
+var _self = function (contact) {
+    return {
+        contact: contact,
+        //readwrite  property  Number   view
+        view: 0
+    };
+};
+
+//const Number  VIEW_NEW  = 0
+_self.__defineGetter__("VIEW_NEW", function () {
+    return 0;
+});
+//const Number  VIEW_COMPOSE  = 1
+_self.__defineGetter__("VIEW_COMPOSE", function () {
+    return 1;
+});
+//const Number  VIEW_DISPLAY  = 2
+_self.__defineGetter__("VIEW_DISPLAY", function () {
+    return 2;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/blackberry', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var blackberry = {},
+    transport = require('ripple/platform/webworks.core/2.0.0/client/transport');
+
+blackberry.__defineGetter__("network", function () {
+    return transport.call("blackberry/system/network");
+});
+
+module.exports = blackberry;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/FilterExpression', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.find.FilterExpression ( leftField  : object ,  operator  : object ,  rightField : object ,  [negate : Boolean ] )
+var FilterExpression = function (leftField, operator, rightField, negate) {
+    this.__defineGetter__("leftField", function () {
+        return leftField;
+    });
+
+    this.__defineGetter__("operator", function () {
+        return operator;
+    });
+
+    this.__defineGetter__("rightField", function () {
+        return rightField;
+    });
+
+    this.__defineGetter__("negate", function () {
+        return negate ? true : false;
+    });
+};
+
+module.exports = FilterExpression;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/BrowserArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.BrowserArguments ( url : String ,  [transport : blackberry.identity.Transport ] )
+module.exports = function (url, transport) {
+    return {
+        url: url
+    };
+};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/MapsArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.MapsArguments ( )
+//blackberry.invoke.MapsArguments ( latitude : Number ,  longitude : Number )
+//blackberry.invoke.MapsArguments ( locationDocument : Document ) - Supported in 5.0.0 only
+//blackberry.invoke.MapsArguments ( locationDocument : String ) - Supported in 6.0.0 only
+//blackberry.invoke.MapsArguments ( address : blackberry.pim.Address )
+var _self = function () {
+    return {};
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/dialog', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self = {
+    customAsk: function (message, choices, defaultChoice, globalStatus) {
+        throw "not implemented";
+    },
+
+    standardAsk: function (specifies, message, defaultChoice, globalStatus) {
+        throw "not implemented";
+    }
+};
+
+_self.__defineGetter__("D_OK", function () {
+    return 0;
+});
+
+_self.__defineGetter__("D_SAVE", function () {
+    return 1;
+});
+
+_self.__defineGetter__("D_DELETE", function () {
+    return 2;
+});
+
+_self.__defineGetter__("D_YES_NO", function () {
+    return 3;
+});
+
+_self.__defineGetter__("D_OK_CANCEL", function () {
+    return 4;
+});
+
+_self.__defineGetter__("C_CANCEL", function () {
+    return -1;
+});
+
+_self.__defineGetter__("C_OK", function () {
+    return 0;
+});
+
+_self.__defineGetter__("C_SAVE", function () {
+    return 1;
+});
+
+_self.__defineGetter__("C_DISCARD", function () {
+    return 2;
+});
+
+_self.__defineGetter__("C_DELETE", function () {
+    return 3;
+});
+
+_self.__defineGetter__("C_YES", function () {
+    return 4;
+});
+
+_self.__defineGetter__("C_NO", function () {
+    return -1;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/appEvent', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _callbacks = {},
+    _self;
+
+function _poll(evt, handler) {
+    _callbacks[evt] = handler;
+
+    transport.poll("blackberry/app/event/" + evt, {}, function () {
+        var func = _callbacks[evt];
+
+        if (func) {
+            func();
+        }
+
+        return !!func;
+    });
+}
+
+_self = {
+    onBackground: function (handler) {
+        _poll("onBackground", handler);
+    },
+
+    onForeground: function (handler) {
+        _poll("onForeground", handler);
+    },
+
+    onExit: function (handler) {
+        _poll("onExit", handler);
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/PhoneCall', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function PhoneCall(onhold) {
+    return {
+        //Boolean   isOnHold ( )
+        //readonly  property  Boolean   outgoing
+        //readonly  property  String   recipientName
+        //readonly  property  String   recipientNumber
+
+        outgoing: false,
+        recipientName: null,
+        recipientNumber: null,
+
+        isOnHold: function () {
+            return onhold;
+        }
+    };
+}
+
+module.exports = PhoneCall;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/MemoArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.MemoArguments ( [memo : blackberry.pim.Memo ] )
+var _self = function (memo) {
+    return {
+        memo: memo,
+        view: 0
+    };
+};
+
+//const Number  VIEW_NEW  = 0
+_self.__defineGetter__("VIEW_NEW", function () {
+    return 0;
+});
+//const Number  VIEW_EDIT  = 1
+_self.__defineGetter__("VIEW_EDIT", function () {
+    return 1;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/Appointment', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    utils = require('ripple/utils'),
+    _uri = "blackberry/pim/appointment/";
+
+function Appointment(service) {
+    var _self = {
+        allDay: false,
+        attendees: [],
+        end: null,
+        freeBusy: null,
+        location: null,
+        note: null,
+        recurrence: null,
+        reminder: null,
+        start: null,
+        summary: null,
+        uid: null,
+        remove: function () {
+            transport.call(_uri + "remove", {get: {uid: _self.uid}});
+        },
+        save: function () {
+            if (_self.uid === null) {
+                _self.uid  = Number(Math.uuid(8, 10));
+            }
+            transport.call(_uri + "save", {post: {appointment: _self}});
+        }
+    };
+
+    return _self;
+}
+
+function _massage(property, name) {
+    if (name === "recurrence" && property) {
+        if (property.end) {
+            property.end = new Date(property.end);
+        }
+    }
+    if (name === "reminder" && property) {
+        if (property.date) {
+            property.date = new Date(property.date);
+        }
+    }
+    if ((name === "end" || name === "start") && property) {
+        property = new Date(property);
+    }
+    return property;
+}
+
+Appointment.find = function (filter, orderBy, maxReturn, service, isAscending) {
+    var opts = {
+        post: {
+            filter: filter,
+            orderBy: orderBy,
+            maxReturn: maxReturn,
+            service: service,
+            isAscending: isAscending
+        }
+    };
+
+    return transport.call(_uri + "find", opts).map(function (obj) {
+        var appt = new Appointment();
+        appt.allDay = obj.allDay;
+        appt.attendees = obj.attendees;
+        appt.end = _massage(obj.end, "end");
+        appt.freeBusy = obj.freeBusy;
+        appt.location = obj.location;
+        appt.note = obj.note;
+        appt.recurrence = _massage(obj.recurrence, "recurrence");
+        appt.reminder = _massage(obj.reminder, "reminder");
+        appt.start = _massage(obj.start, "start");
+        appt.summary = obj.summary;
+        appt.uid = obj.uid;
+        return appt;
+    });
+};
+
+Appointment.__defineGetter__("FREE", function () {
+    return 0;
+});
+Appointment.__defineGetter__("TENTATIVE", function () {
+    return 1;
+});
+Appointment.__defineGetter__("BUSY", function () {
+    return 2;
+});
+Appointment.__defineGetter__("OUT_OF_OFFICE", function () {
+    return 3;
+});
+
+module.exports = Appointment;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/Message', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/platform/webworks.core/2.0.0/client/utils'),
+    identity = require('ripple/platform/webworks.handset/2.0.0/client/identity'),
+    transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    Service = require('ripple/platform/webworks.handset/2.0.0/client/identity/Service'),
+    select = require('ripple/platform/webworks.core/2.0.0/select'),
+    _uri = "blackberry/message/message/";
+
+function Message(service) {
+    var _service = service,
+        _msg = {
+            uid: 0,
+            status: Message.STATUS_DRAFT,
+            from: "",
+            folder: Message.FOLDER_DRAFT,
+            replyTo: "",
+            bccRecipients: "",
+            body: "",
+            ccRecipients: "",
+            priority: Message.PRIORITY_MEDIUM, //default to med priority
+            subject: "",
+            toRecipients: "",
+
+            remove: function () {
+                _msg.folder = Message.FOLDER_DELETED;
+                transport.call(_uri + "remove", {
+                    get: {uid: _msg.uid}
+                });
+            },
+
+            save: function () {
+                if (_msg.uid === 0) {
+                    _msg.uid = Number(Math.uuid(8, 10));
+                }
+
+                _msg.replyTo  = _msg.from = _service.emailAddress;
+                _msg.status =  Message.STATUS_SAVED;
+                transport.call(_uri + "save", {
+                    post: {message: _msg}
+                });
+            },
+
+            send: function () {
+                if (_msg.toRecipients) {
+                    if (_msg.uid === 0) {
+                        _msg.uid = Number(Math.uuid(8, 10));
+                    }
+
+                    _msg.folder = Message.FOLDER_DRAFT;
+                    _msg.status = Message.STATUS_UNKNOWN;
+                    transport.call(_uri + "send", {
+                        get: {message: _msg}
+                    });
+                } else {
+                    throw "message has no recipients";
+                }
+            }
+        };
+
+    if (!_service) {
+        _service = identity.getDefaultService().reduce(function (email, service) {
+            return service.type === Service.TYPE_EMAIL ? service : email;
+        }, null);
+    }
+
+    return _msg;
+}
+
+Message.find = function (filter, maxReturn, service) {
+    var opts = {
+        post: {
+            filter: filter,
+            maxReturn: maxReturn,
+            service: service
+        }
+    };
+
+    return transport.call(_uri + "find", opts).map(function (obj) {
+        var msg = new Message();
+
+        msg.uid = obj.uid;
+        msg.status = obj.status;
+        msg.from = obj.from;
+        msg.folder = obj.folder;
+        msg.replyTo = obj.replyTo;
+        msg.bccRecipients = obj.bccRecipients;
+        msg.body = obj.body;
+        msg.ccRecipients = obj.ccRecipients;
+        msg.priority = obj.priority;
+        msg.subject = obj.subject;
+        msg.toRecipients = obj.toRecipients;
+
+        return msg;
+    });
+};
+
+
+Message.__defineGetter__("STATUS_UNKNOWN", function () {
+    return -1;
+});
+Message.__defineGetter__("STATUS_SAVED", function () {
+    return 0;
+});
+Message.__defineGetter__("STATUS_DRAFT", function () {
+    return 1;
+});
+Message.__defineGetter__("STATUS_SENT", function () {
+    return 2;
+});
+Message.__defineGetter__("STATUS_ERROR_OCCURED", function () {
+    return 3;
+});
+Message.__defineGetter__("PRIORITY_HIGH", function () {
+    return 0;
+});
+Message.__defineGetter__("PRIORITY_MEDIUM", function () {
+    return 1;
+});
+Message.__defineGetter__("PRIORITY_LOW", function () {
+    return 2;
+});
+Message.__defineGetter__("FOLDER_INBOX", function () {
+    return 0;
+});
+Message.__defineGetter__("FOLDER_SENT", function () {
+    return 1;
+});
+Message.__defineGetter__("FOLDER_DRAFT", function () {
+    return 2;
+});
+Message.__defineGetter__("FOLDER_OUTBOX", function () {
+    return 3;
+});
+Message.__defineGetter__("FOLDER_DELETED", function () {
+    return 4;
+});
+Message.__defineGetter__("FOLDER_OTHER", function () {
+    return 5;
+});
+
+module.exports = Message;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/MenuItem', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    event = require('ripple/event');
+
+function MenuItem(isSeparator, ordinal, caption, callback) {
+    var _isDefault = false,
+       id = Math.uuid();
+
+    if (ordinal < 0) {
+        throw "Ordinal cannot be less than 0";
+    } else if (isSeparator) {
+        if (caption !== undefined) {
+            throw "caption must not be supplied";
+        } else if (callback !== undefined) {
+            throw "callback must not be supplied";
+        }
+    } else if (!isSeparator) {
+        if (caption === undefined) {
+            throw "caption must be supplied";
+        }
+    }
+
+    this.callback = callback;
+
+    this.__defineSetter__("id", function (i) {
+        id = i;
+    });
+
+    this.__defineGetter__("id", function () {
+        return id;
+    });
+
+    this.__defineSetter__("caption", function (c) {
+        caption = c;
+        event.trigger("MenuItemChanged", [this]);
+    });
+
+    this.__defineGetter__("caption", function () {
+        return caption;
+    });
+
+    this.__defineSetter__("ordinal", function (o) {
+        ordinal = o;
+        event.trigger("MenuItemChanged", [this]);
+    });
+
+    this.__defineGetter__("ordinal", function () {
+        return ordinal;
+    });
+
+    this.__defineGetter__("isSeparator", function () {
+        return isSeparator;
+    });
+
+    this.__defineSetter__("isDefault", function (d) {
+        _isDefault = d;
+        event.trigger("MenuItemChanged", [this]);
+    });
+
+    this.__defineGetter__("isDefault", function () {
+        return _isDefault;
+    });
+
+    this.__defineGetter__("id", function () {
+        return id;
+    });
+}
+
+module.exports = MenuItem;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/app', function (require, module, exports) {
+/*\r
+ *  Copyright 2011 Research In Motion Limited.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
+    _uri = "blackberry/app/",\r
+    _self;\r
+\r
+_self = {\r
+    exit: function () {\r
+        transport.call(_uri + "exit", {async: true});\r
+    },\r
+\r
+    setHomeScreenIcon: function (uri, hover) {\r
+        transport.call(_uri + "setHomeScreenIcon", {\r
+            get: {\r
+                uri: uri,\r
+                hover: hover\r
+            },\r
+            async: true\r
+        });\r
+\r
+        return true;\r
+    },\r
+\r
+    setHomeScreenName: function (text) {\r
+        transport.call(_uri + "setHomeScreenName", {\r
+            get: {text: text},\r
+            async: true\r
+        });\r
+\r
+        return true;\r
+    },\r
+\r
+    requestForeground: function () {\r
+        transport.call(_uri + "requestForeground", {async: true});\r
+    },\r
+\r
+    requestBackground: function () {\r
+        transport.call(_uri + "requestBackground", {async: true});\r
+    },\r
+\r
+    removeBannerIndicator: function () {\r
+        transport.call(_uri + "removeBannerIndicator", {async: true});\r
+    },\r
+\r
+    showBannerIndicator: function (icon, count) {\r
+        transport.call(_uri + "showBannerIndicator", {\r
+            get: {\r
+                icon: icon,\r
+                count: count\r
+            },\r
+            async: true\r
+        });\r
+    },\r
+};\r
+\r
+_self.__defineGetter__("author", function () {\r
+    return transport.call(_uri + "author");\r
+});\r
+\r
+_self.__defineGetter__("authorEmail", function () {\r
+    return transport.call(_uri + "authorEmail");\r
+});\r
+\r
+_self.__defineGetter__("authorURL", function () {\r
+    return transport.call(_uri + "authorURL");\r
+});\r
+\r
+_self.__defineGetter__("copyright", function () {\r
+    return transport.call(_uri + "copyright");\r
+});\r
+\r
+_self.__defineGetter__("description", function () {\r
+    return transport.call(_uri + "description");\r
+});\r
+\r
+_self.__defineGetter__("id", function () {\r
+    return transport.call(_uri + "id");\r
+});\r
+\r
+_self.__defineGetter__("isForeground", function () {\r
+    return transport.call(_uri + "isForeground");\r
+});\r
+\r
+_self.__defineGetter__("license", function () {\r
+    return transport.call(_uri + "license");\r
+});\r
+\r
+_self.__defineGetter__("licenseURL", function () {\r
+    return transport.call(_uri + "licenseURL");\r
+});\r
+\r
+_self.__defineGetter__("name", function () {\r
+    return transport.call(_uri + "name");\r
+});\r
+\r
+_self.__defineGetter__("version", function () {\r
+    return transport.call(_uri + "version");\r
+});\r
+\r
+module.exports = _self;\r
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/Memo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/pim/memo/";
+
+function Memo() {
+    var _self = {
+        categories: [],
+        note: null,
+        title: null,
+        uid: null,
+        remove: function () {
+            transport.call(_uri + "remove", {
+                get: {uid: _self.uid}
+            });
+        },
+        save: function () {
+            if (_self.uid  === null) {
+                _self.uid  = Number(Math.uuid(8, 10));
+            }
+            transport.call(_uri + "save", {
+                post: {memo: _self}
+            });
+        }
+    };
+
+    return _self;
+}
+
+Memo.find = function (filter, orderBy, maxReturn, service, isAscending) {
+    var opts = {
+        post: {
+            filter: filter,
+            orderBy: orderBy,
+            maxReturn: maxReturn,
+            isAscending: isAscending,
+            service: service
+        }
+    };
+
+    return transport.call(_uri + "find", opts).map(function (obj) {
+        var memo = new Memo();
+        memo.uid = obj.uid;
+        memo.categories = obj.categories || [];
+        memo.note = obj.note;
+        memo.title = obj.title;
+        return memo;
+    });
+};
+
+module.exports = Memo;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/TaskArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.TaskArguments ( [task : blackberry.pim.Task ] )
+var _self = function (task) {
+    return {
+        view: 0,
+        task: task
+    };
+};
+
+//const Number  VIEW_NEW  = 0
+_self.__defineGetter__("VIEW_NEW", function () {
+    return 0;
+});
+//const Number  VIEW_EDIT  = 1
+_self.__defineGetter__("VIEW_EDIT", function () {
+    return 1;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/Contact', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/pim/contact/";
+
+function Contact(service) {
+    var _self = {
+        anniversary: null,
+        birthday: null,
+        categories: [],
+        company: null,
+        email1: null,
+        email2: null,
+        email3: null,
+        faxPhone: null,
+        firstName: null,
+        homeAddress: null,
+        homePhone: null,
+        homePhone2: null,
+        jobTitle: null,
+        lastName: null,
+        mobilePhone: null,
+        note: null,
+        otherPhone: null,
+        pagerPhone: null,
+        picture: null,
+        pin: null,
+        title: null,
+        uid: null,
+        user1: null,
+        user2: null,
+        user3: null,
+        user4: null,
+        webpage: null,
+        workAddress: null,
+        workPhone: null,
+        workPhone2: null,
+        remove: function () {
+            if (!_self.uid) {
+                throw "task has not yet been saved (has no uid)";
+            }
+            transport.call(_uri + "remove", {
+                get: { id: _self.uid }
+            });
+        },
+        save: function () {
+            if (!_self.uid) {
+                _self.uid = Math.uuid(null, 16);
+            }
+            transport.call(_uri + "save", {
+                post: { contact: _self }
+            });
+        },
+        setPicture: function (picture) {
+            throw "not implemented";
+        }
+    };
+
+    return _self;
+}
+
+function _massage(property, name) {
+    if ((name === "anniversary" || name === "birthday") && property) {
+        return new Date(property);
+    }
+    return property;
+}
+
+Contact.find = function (fieldFilter, orderBy, maxReturn, service, isAscending) {
+    return transport.call(_uri + "find", {
+        post: {
+            fieldFilter: fieldFilter,
+            orderBy: orderBy,
+            maxReturn: maxReturn,
+            service: service,
+            isAscending: isAscending
+        }
+    }).map(function (properties) {
+        var contact = new Contact(),
+            key;
+        for (key in properties) {
+            if (contact.hasOwnProperty(key)) {
+                contact[key] = _massage(properties[key], key);
+            }
+        }
+        return contact;
+    });
+};
+
+module.exports = Contact;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/sms', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/message/sms/",
+    onReceive,
+    _self;
+
+_self = {
+    addReceiveListener: function (callback) {
+        onReceive = callback;
+        transport.poll(_uri + "onReceive", {}, function (response) {
+            if (onReceive) {
+                onReceive(response.body, response.from, response.time);
+            }
+            return !!onReceive;
+        });
+    },
+
+    removeReceiveListener: function () {
+        if (onReceive) {
+            onReceive = null;
+            return true;
+        }
+
+        return false;
+    },
+
+    send: function (message, address) {
+        transport.call(_uri + "send", {
+            get: {
+                message: message,
+                address: address
+            },
+            async: true
+        });
+    }
+};
+
+_self.__defineGetter__("isListeningForMessage", function () {
+    return transport.call(_uri + "isListeningForMessage", {async: false});
+});
+
+_self.__defineSetter__("isListeningForMessage", function (value) {
+    transport.call(_uri + "isListeningForMessage", {
+        async: false,
+        get: {isListeningForMessage: value}
+    });
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/pim', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/io/dir', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    dir = require('ripple/platform/webworks.core/2.0.0/client/io/dir'),
+    utils = require('ripple/utils'),
+    _uri = "blackberry/io/dir/",
+    FILE = "file://",
+    _self = {};
+
+function _prunePrefix(path) {
+    return path.replace(new RegExp("^" + FILE), '');
+}
+
+utils.mixin({
+    getFreeSpaceForRoot: function (path) {
+        return transport.call(_uri + "getFreeSpaceForRoot", {
+            post: {path: _prunePrefix(path)}
+        });
+    },
+    getRootDirs: function () {
+        return transport.call(_uri + "getRootDirs", {}).map(function (dir) {
+            return FILE + dir;
+        });
+    }
+}, _self);
+
+utils.mixin(dir, _self);
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/push', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _self,
+    _uri = "blackberry/push/onPush",
+    callbacks = {},
+    PushData = require('ripple/platform/webworks.handset/2.0.0/client/PushData');
+
+_self = {
+    openPushListener: function (callback, port, bbTransport, maxQueueCap) {
+        callbacks["onPush" + port] = callback;
+
+        transport.poll(_uri, {
+            get: {
+                port: port,
+                bbTransport: bbTransport,
+                maxQueueCap: maxQueueCap
+            }
+        }, function (response) {
+            var func = callbacks["onPush" + port];
+
+            if (func) {
+                func(new PushData(response, port));
+            }
+
+            return !!func;
+        });
+    },
+
+    closePushListener: function (port) {
+        delete callbacks["onPush" + port];
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/Recurrence', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function Recurrence() {
+    return {
+        //readwrite  property  Number   count
+        //readwrite  property  Number   dayInMonth
+        //readwrite  property  Number   dayInWeek
+        //readwrite  property  Number   dayInYear
+        //readwrite  property  Date   end
+        //readwrite  property  Number   frequency
+        //readwrite  property  Number   interval
+        //readwrite  property  Number   monthInYear
+        //readwrite  property  Number   weekInMonth
+
+        count: null,
+        dayInMonth: null,
+        dayInWeek: null,
+        dayInYear: null,
+        end: null,
+        frequency: null,
+        interval: null,
+        monthInYear: null,
+        weekInMonth: null
+    };
+}
+
+Recurrence.__defineGetter__("NO_REPEAT", function () {
+    return 0;
+});
+Recurrence.__defineGetter__("DAILY", function () {
+    return 1;
+});
+Recurrence.__defineGetter__("WEEKLY", function () {
+    return 2;
+});
+Recurrence.__defineGetter__("MONTHLY", function () {
+    return 3;
+});
+Recurrence.__defineGetter__("YEARLY", function () {
+    return 4;
+});
+Recurrence.__defineGetter__("JANUARY", function () {
+    return 0x20000;
+});
+Recurrence.__defineGetter__("FEBRUARY", function () {
+    return 0x40000;
+});
+Recurrence.__defineGetter__("MARCH", function () {
+    return 0x80000;
+});
+Recurrence.__defineGetter__("APRIL", function () {
+    return 0x100000;
+});
+Recurrence.__defineGetter__("MAY", function () {
+    return 0x200000;
+});
+Recurrence.__defineGetter__("JUNE", function () {
+    return 0x400000;
+});
+Recurrence.__defineGetter__("JULY", function () {
+    return 0x800000;
+});
+Recurrence.__defineGetter__("AUGUST", function () {
+    return 0x1000000;
+});
+Recurrence.__defineGetter__("SEPTEMBER", function () {
+    return 0x2000000;
+});
+Recurrence.__defineGetter__("OCTOBER", function () {
+    return 0x4000000;
+});
+Recurrence.__defineGetter__("NOVEMBER", function () {
+    return 0x8000000;
+});
+Recurrence.__defineGetter__("DECEMBER", function () {
+    return 0x10000000;
+});
+Recurrence.__defineGetter__("FIRST", function () {
+    return 0x1;
+});
+Recurrence.__defineGetter__("SECOND", function () {
+    return 0x2;
+});
+Recurrence.__defineGetter__("THIRD", function () {
+    return 0x4;
+});
+Recurrence.__defineGetter__("FOURTH", function () {
+    return 0x8;
+});
+Recurrence.__defineGetter__("FIFTH", function () {
+    return 0x10;
+});
+Recurrence.__defineGetter__("LAST", function () {
+    return 0x20;
+});
+Recurrence.__defineGetter__("SECONDLAST", function () {
+    return 0x40;
+});
+Recurrence.__defineGetter__("THIRDLAST", function () {
+    return 0x80;
+});
+Recurrence.__defineGetter__("FOURTHLAST", function () {
+    return 0x100;
+});
+Recurrence.__defineGetter__("FIFTHLAST", function () {
+    return 0x200;
+});
+Recurrence.__defineGetter__("SUNDAY", function () {
+    return 0x10000;
+});
+Recurrence.__defineGetter__("MONDAY", function () {
+    return 0x8000;
+});
+Recurrence.__defineGetter__("TUESDAY", function () {
+    return 0x4000;
+});
+Recurrence.__defineGetter__("WEDNESDAY", function () {
+    return 0x2000;
+});
+Recurrence.__defineGetter__("THURSDAY", function () {
+    return 0x1000;
+});
+Recurrence.__defineGetter__("FRIDAY", function () {
+    return 0x800;
+});
+Recurrence.__defineGetter__("SATURDAY", function () {
+    return 0x400;
+});
+
+module.exports = Recurrence;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/system', function (require, module, exports) {
+var utils = require('ripple/utils'),
+    transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    system = require('ripple/platform/webworks.core/2.0.0/client/system'),
+    _uri = "blackberry/system/",
+    _self;
+
+_self = {
+    setHomeScreenBackground: function (filePath) {
+        transport.call(_uri + "setHomeScreenBackground", {
+            get: {filePath: filePath},
+            async: true
+        });
+    },
+};
+
+(function () {
+    // HACK: can't type check if system[key] is a function, sets off getters
+    // also can't use utils.mixin or forEach for the same reason
+    function get(i) {
+        return function () {
+            return system[i];
+        };
+    }
+
+    for (var key in system) {
+        if (system.hasOwnProperty(key)) {
+            _self.__defineGetter__(key, get(key));
+        }
+    }
+}());
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/invoke', function (require, module, exports) {
+/*\r
+ *  Copyright 2011 Research In Motion Limited.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+var _uri = "blackberry/invoke/invoke",\r
+    APP_URL_CAMERA = "camera://",\r
+    APP_URL_CAMERA_VIDEO = "camera://video",\r
+    APP_URL_MAP = "map://",\r
+    APP_URL_MUSIC = "music://",\r
+    APP_URL_PHOTOS = "photos://",\r
+    APP_URL_VIDEOS = "videos://",\r
+    APP_URL_APPWORLD = "appworld://",\r
+    APP_URL_UPDATE = "update://",\r
+    APP_BROWSER_ERROR = "Protocol specified in the url is not supported.",\r
+    APP_ADDRESSBOOK_ERROR = "Invalid arguments specified",\r
+    transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
+    _self;\r
+\r
+_self = {\r
+    invoke: function (appType, args) {\r
+        var get = {};\r
+\r
+        switch (appType) {\r
+\r
+        //AddressBook\r
+        case 0:\r
+            if (args) {\r
+                if (args.view === 1 && args.contact) {\r
+                    throw APP_ADDRESSBOOK_ERROR; //contact cannot be used with this view\r
+                }\r
+                else if (args.view === 2 && !args.contact) {\r
+                    throw APP_ADDRESSBOOK_ERROR; //need contact for this view\r
+                }\r
+            }\r
+\r
+            get.appType = appType;\r
+            break;\r
+\r
+        //Bluetooth Config\r
+        case 1:\r
+            get.appType = appType;\r
+            break;\r
+\r
+        //Calculator\r
+        case 2:\r
+            get.appType = appType;\r
+            break;\r
+\r
+        //Calendar\r
+        case 3:\r
+            get.appType = appType;\r
+            break;\r
+\r
+        //Camera\r
+        case 4:\r
+            if (!args || args.view === 1) {\r
+                get.appType = APP_URL_CAMERA_VIDEO;\r
+            } else {\r
+                get.appType = APP_URL_CAMERA;\r
+            }\r
+            break;\r
+\r
+        //Maps\r
+        case 5:\r
+            get.appType = APP_URL_MAP;\r
+            break;\r
+\r
+        //Memopad\r
+        case 6:\r
+            get.appType = appType;\r
+            break;\r
+\r
+        //Messages\r
+        case 7:\r
+            get.appType = appType;\r
+            break;\r
+\r
+        //Phone\r
+        case 8:\r
+            get.appType = appType;\r
+            break;\r
+\r
+        //Search\r
+        case 9:\r
+            get.appType = appType;\r
+            break;\r
+\r
+        //Tasks\r
+        case 10:\r
+            get.appType = appType;\r
+            break;\r
+\r
+        //Browser\r
+        case 11:\r
+\r
+            if (!args) {\r
+                get.appType = "http://";\r
+            } else {\r
+                if (args.url && !args.url.match(/^https?:\/\//)) {\r
+                    throw APP_BROWSER_ERROR;\r
+                }\r
+                get.appType = args.url;\r
+            }\r
+\r
+            break;\r
+\r
+        //Java\r
+        case 12:\r
+            get.appType = appType;\r
+            break;\r
+\r
+        default:\r
+            throw "appType not supported";\r
+        }\r
+\r
+        transport.call(_uri, {\r
+            get: get,\r
+            async: true\r
+        });\r
+    }\r
+};\r
+\r
+_self.__defineGetter__("APP_ADDRESSBOOK", function () {\r
+    return 0;\r
+});\r
+_self.__defineGetter__("APP_BLUETOOTH_CONFIG", function () {\r
+    return 1;\r
+});\r
+_self.__defineGetter__("APP_CALCULATOR", function () {\r
+    return 2;\r
+});\r
+_self.__defineGetter__("APP_CALENDAR", function () {\r
+    return 3;\r
+});\r
+_self.__defineGetter__("APP_CAMERA", function () {\r
+    return 4;\r
+});\r
+_self.__defineGetter__("APP_MAPS", function () {\r
+    return 5;\r
+});\r
+_self.__defineGetter__("APP_MEMOPAD", function () {\r
+    return 6;\r
+});\r
+_self.__defineGetter__("APP_MESSAGES", function () {\r
+    return 7;\r
+});\r
+_self.__defineGetter__("APP_PHONE", function () {\r
+    return 8;\r
+});\r
+_self.__defineGetter__("APP_SEARCH", function () {\r
+    return 9;\r
+});\r
+_self.__defineGetter__("APP_TASKS", function () {\r
+    return 10;\r
+});\r
+_self.__defineGetter__("APP_BROWSER", function () {\r
+    return 11;\r
+});\r
+_self.__defineGetter__("APP_JAVA", function () {\r
+    return 12;\r
+});\r
+\r
+module.exports = _self;\r
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/Phone', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/phone/",
+    _listeners = {},
+    _self;
+
+_self = {
+    activeCalls: function () {
+        return transport.call(_uri + "activeCalls");
+    },
+
+    addPhoneListener: function (callback, eventType) {
+        var assigned = false;
+
+        if (callback && typeof eventType === "number") {
+            _listeners[eventType] = callback;
+            assigned = true;
+        } else if (eventType && callback === null) {
+            delete _listeners[eventType];
+        } else {
+            _listeners = {};
+        }
+
+        transport.poll(_uri + "onPhoneEvent", {
+            get: {eventType: eventType}
+        }, function (response) {
+            var func = _listeners[eventType];
+
+            if (func) {
+                func(response.callId, response.error);
+            }
+
+            return !!func;
+        });
+
+        // hackish (return true that event was assigned, this is a disconnect between transport poll api and server)
+        return assigned;
+    },
+
+    inActiveCall: function () {
+        return transport.call(_uri + "inActiveCall");
+    }
+};
+
+_self.__defineGetter__("CB_CALL_INITIATED", function () {
+    return 0;
+});
+_self.__defineGetter__("CB_CALL_WAITING", function () {
+    return 1;
+});
+_self.__defineGetter__("CB_CALL_INCOMING", function () {
+    return 2;
+});
+_self.__defineGetter__("CB_CALL_ANSWERED", function () {
+    return 3;
+});
+_self.__defineGetter__("CB_CALL_CONNECTED", function () {
+    return 4;
+});
+_self.__defineGetter__("CB_CALL_CONFERENCECALL_ESTABLISHED", function () {
+    return 5;
+});
+_self.__defineGetter__("CB_CONFERENCECALL_DISCONNECTED", function () {
+    return 6;
+});
+_self.__defineGetter__("CB_CALL_DISCONNECTED", function () {
+    return 7;
+});
+_self.__defineGetter__("CB_CALL_DIRECTCONNECT_CONNECTED", function () {
+    return 8;
+});
+_self.__defineGetter__("CB_CALL_DIRECTCONNECT_DISCONNECTED", function () {
+    return 9;
+});
+_self.__defineGetter__("CB_CALL_ENDED_BYUSER", function () {
+    return 10;
+});
+_self.__defineGetter__("CB_CALL_FAILED", function () {
+    return 11;
+});
+_self.__defineGetter__("CB_CALL_RESUMED", function () {
+    return 12;
+});
+_self.__defineGetter__("CB_CALL_HELD", function () {
+    return 13;
+});
+_self.__defineGetter__("CB_CALL_ADDED", function () {
+    return 14;
+});
+_self.__defineGetter__("CB_CALL_REMOVED", function () {
+    return 15;
+});
+_self.__defineGetter__("CALL_ERROR_SUBSCRIBER_BUSY", function () {
+    return 1;
+});
+_self.__defineGetter__("CALL_ERROR_CONGESTION", function () {
+    return 2;
+});
+_self.__defineGetter__("CALL_ERROR_RADIO_PATH_UNAVAILABLE", function () {
+    return 3;
+});
+_self.__defineGetter__("CALL_ERROR_NUMBER_UNOBTAINABLE", function () {
+    return 4;
+});
+_self.__defineGetter__("CALL_ERROR_AUTHORIZATION_FAILURE", function () {
+    return 5;
+});
+_self.__defineGetter__("CALL_ERROR_EMERGENCY_CALLS_ONLY", function () {
+    return 6;
+});
+_self.__defineGetter__("CALL_ERROR_HOLD_ERROR", function () {
+    return 7;
+});
+_self.__defineGetter__("CALL_ERROR_OUTGOING_CALLS_BARRED", function () {
+    return 8;
+});
+_self.__defineGetter__("CALL_ERROR_GENERAL", function () {
+    return 9;
+});
+_self.__defineGetter__("CALL_ERROR_MAINTENANCE_REQUIRED", function () {
+    return 10;
+});
+_self.__defineGetter__("CALL_ERROR_SERVICE_NOT_AVAILABLE", function () {
+    return 11;
+});
+_self.__defineGetter__("CALL_ERROR_DUE_TO_FADING", function () {
+    return 12;
+});
+_self.__defineGetter__("CALL_ERROR_LOST_DUE_TO_FADING", function () {
+    return 13;
+});
+_self.__defineGetter__("CALL_ERROR_TRY_AGAIN", function () {
+    return 14;
+});
+_self.__defineGetter__("CALL_ERROR_FDN_MISMATCH", function () {
+    return 15;
+});
+_self.__defineGetter__("CALL_ERROR_CONNECTION_DENIED_BY_NETWORK", function () {
+    return 16;
+});
+_self.__defineGetter__("CALL_ERROR_NUMBER_NOT_IN_SERVICE", function () {
+    return 17;
+});
+_self.__defineGetter__("CALL_ERROR_PLEASE_TRY_LATER", function () {
+    return 18;
+});
+_self.__defineGetter__("CALL_ERROR_SERVICE_CONFLICT", function () {
+    return 19;
+});
+_self.__defineGetter__("CALL_ERROR_SYSTEM_BUSY_TRY_LATER", function () {
+    return 20;
+});
+_self.__defineGetter__("CALL_ERROR_USER_BUSY_IN_PRIVATE", function () {
+    return 21;
+});
+_self.__defineGetter__("CALL_ERROR_USER_BUSY_IN_DATA", function () {
+    return 22;
+});
+_self.__defineGetter__("CALL_ERROR_USER_NOT_AUTHORIZED", function () {
+    return 23;
+});
+_self.__defineGetter__("CALL_ERROR_USER_NOT_AVAILABLE", function () {
+    return 24;
+});
+_self.__defineGetter__("CALL_ERROR_USER_UNKNOWN", function () {
+    return 25;
+});
+_self.__defineGetter__("CALL_ERROR_USER_NOT_REACHABLE", function () {
+    return 26;
+});
+_self.__defineGetter__("CALL_ERROR_INCOMING_CALL_BARRED", function () {
+    return 27;
+});
+_self.__defineGetter__("CALL_ERROR_CALL_REPLACED_BY_STK", function () {
+    return 28;
+});
+_self.__defineGetter__("CALL_ERROR_STK_CALL_NOT_ALLOWED", function () {
+    return 29;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/PhoneLogs', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    CallLog = require('ripple/platform/webworks.handset/2.0.0/client/CallLog'),
+    utils = require('ripple/utils'),
+    _onCallLog = {
+        Added: null,
+        Removed: null,
+        Updated: null,
+        Reset: null,
+    },
+    _uri = "blackberry/phone/logs/",
+    _self;
+
+function _massage(property, name) {
+    if (name === "date" && property) {
+        return new Date(property);
+    }
+    return property;
+}
+
+function _toCallLog(log) {
+    var callLog = new CallLog(),
+        prop;
+    for (prop in log) {
+        if (log.hasOwnProperty(prop)) {
+            callLog[prop] = _massage(log[prop], prop);
+        }
+    }
+    return callLog;
+}
+
+function handle(evt) {
+    return function (response) {
+        var func = _onCallLog[evt], args;
+
+        if (func) {
+            args = utils.map(response, function (value) {
+                return _toCallLog(value);
+            });
+            func.apply(null, args);
+        }
+
+        return !!func;
+    };
+}
+
+function poll(path) {
+    transport.poll(_uri + path, {}, handle(path.replace("onCallLog", "")));
+}
+
+_self = {
+    addPhoneLogListener: function (onCallLogAdded, onCallLogRemoved, onCallLogUpdated, onCallLogReset) {
+        _onCallLog.Added = onCallLogAdded;
+        _onCallLog.Removed = onCallLogRemoved;
+        _onCallLog.Updated = onCallLogUpdated;
+        _onCallLog.Reset = onCallLogReset;
+
+        if (onCallLogAdded) {
+            poll("onCallLogAdded");
+        }
+
+        if (onCallLogRemoved) {
+            poll("onCallLogRemoved");
+        }
+
+        if (onCallLogUpdated) {
+            poll("onCallLogUpdated");
+        }
+
+        if (onCallLogReset) {
+            poll("onCallLogReset");
+        }
+
+        return !!(onCallLogAdded || onCallLogRemoved ||
+                  onCallLogUpdated || onCallLogRemoved);
+    },
+
+    callAt: function (index, folderID) {
+        var log = transport.call(_uri + "callAt", {
+            get: {
+                index: index,
+                folderID: folderID
+            }
+        });
+
+        if (log && log.date) {
+            log.date = new Date(log.date);
+        }
+
+        return log;
+    },
+
+    deleteCallAt: function (index, folderID) {
+        return transport.call(_uri + "deleteCallAt", {
+            get: {
+                index: index,
+                folderID: folderID
+            }
+        });
+    },
+
+    find: function (filter, folderID, orderBy, maxReturn, isAscending) {
+        return transport.call(_uri + "find", {
+            post: {
+                filter: filter,
+                folderID: folderID,
+                orderBy: orderBy,
+                maxReturn: maxReturn,
+                isAscending: isAscending
+            }
+        }).map(_toCallLog);
+    },
+
+    numberOfCalls: function (folderID) {
+        return transport.call(_uri + "numberOfCalls", {
+            get: {
+                folderID: folderID
+            }
+        });
+    }
+};
+
+_self.__defineGetter__("FOLDER_MISSED_CALLS", function () {
+    return 0;
+});
+
+_self.__defineGetter__("FOLDER_NORMAL_CALLS", function () {
+    return 1;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/JavaArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.JavaArguments ( uri : String ,  [params : String [ ] ] )
+var _self = function (uri, params) {
+    return {
+        uri: uri,
+        params: params,
+        args: arguments
+    };
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/MessageArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.MessageArguments ( )
+//blackberry.invoke.MessageArguments ( message : blackberry.message.Message )
+//blackberry.invoke.MessageArguments ( to : String ,  subject : String ,  body : String )
+var _self = function () {
+    return {
+        view: 1
+    };
+};
+
+//const Number  VIEW_NEW  = 0
+_self.__defineGetter__("VIEW_NEW", function () {
+    return 0;
+});
+//const Number  VIEW_DEFAULT  = 1
+_self.__defineGetter__("VIEW_DEFAULT", function () {
+    return 1;
+});
+//const Number  VIEW_SAVED  = 2
+_self.__defineGetter__("VIEW_SAVED", function () {
+    return 2;
+});
+//const Number  VIEW_SEARCH  = 3
+_self.__defineGetter__("VIEW_SEARCH", function () {
+    return 3;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/Address', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function Address() {
+    return {
+        //readwrite  property  String   address1
+        //readwrite  property  String   address2
+        //readwrite  property  String   city
+        //readwrite  property  String   country
+        //readwrite  property  String   stateProvince
+        //readwrite  property  String   zipPostal
+
+        address1: null,
+        address2: null,
+        city: null,
+        country: null,
+        stateProvince: null,
+        zipPostal: null
+    };
+}
+
+module.exports = Address;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/SearchArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.SearchArguments ( )
+//blackberry.invoke.SearchArguments ( text : String ,  name : String )
+var _self = function (text, name) {
+
+    return {
+        text: text,
+        name: name
+    };
+
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/Task', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/pim/Task/";
+
+function Task() {
+    var _self = {
+        save: function () {
+            if (!_self.uid) {
+                _self.uid = Math.uuid(null, 16);
+            }
+            transport.call(_uri + "save",  {
+                post: {
+                    task: _self
+                }
+            });
+        },
+        remove: function () {
+            if (!_self.uid) {
+                throw "task has not yet been saved (has no uid)";
+            }
+            transport.call(_uri + "remove", {
+                get: {
+                    id: _self.uid
+                }
+            });
+        },
+        uid: null,
+        categories: [],
+        due: null,
+        note: "",
+        priority: Task.PRIORITY_NORMAL,
+        recurrence: null,
+        reminder: null,
+        status: Task.NOT_STARTED,
+        summary: ""
+    };
+
+    return _self;
+}
+
+function _massage(property, name) {
+    if (name === "recurrence" && property) {
+        if (property.end) {
+            property.end = new Date(property.end);
+        }
+    }
+    if (name === "reminder" && property) {
+        if (property.date) {
+            property.date = new Date(property.date);
+        }
+    }
+    if (name === "due" && property) {
+        property = new Date(property);
+    }
+    return property;
+}
+
+Task.find = function (filter, orderBy, maxReturn, isAscending) {
+    return transport.call(_uri + "find", {
+        post: {
+            filter: filter,
+            orderBy: orderBy,
+            maxReturn: maxReturn,
+            isAscending: isAscending
+        }
+    }).map(function (properties) {
+        var task = new Task(),
+            key;
+        for (key in properties) {
+            if (task.hasOwnProperty(key)) {
+                task[key] = _massage(properties[key], key);
+            }
+        }
+        return task;
+    });
+};
+
+Task.__defineGetter__("NOT_STARTED", function () {
+    return 0;
+});
+
+Task.__defineGetter__("IN_PROGRESS", function () {
+    return 1;
+});
+
+Task.__defineGetter__("COMPLETED", function () {
+    return 2;
+});
+
+Task.__defineGetter__("WAITING", function () {
+    return 3;
+});
+
+Task.__defineGetter__("DEFERRED", function () {
+    return 4;
+});
+
+Task.__defineGetter__("PRIORITY_HIGH", function () {
+    return 0;
+});
+
+Task.__defineGetter__("PRIORITY_NORMAL", function () {
+    return 1;
+});
+
+Task.__defineGetter__("PRIORITY_LOW", function () {
+    return 2;
+});
+
+module.exports = Task;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/AudioPlayer', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/audio/player/";
+
+function Player(locator, type, async) {
+    //we can't use the async prop since we need the ID before we can do anything else.
+    var _id = transport.call(_uri + "create", {
+            get: {locator: locator, type: type},
+            async: false
+        }),
+        _listener,
+        _closed,
+        _self,
+        _poll = function (path) {
+            transport.poll(_uri + path, {
+                get: {id: _id}
+            }, function (response) {
+                if (_listener) {
+                    _listener(_self, response.event, response.eventData);
+                }
+
+                return !!_listener;
+            });
+        };
+
+    _self = {
+        addPlayerListener: function (callback) {
+            if (!_closed && callback) {
+                _listener = callback;
+                _poll("onStart");
+                _poll("onStopped");
+                _poll("onBufferingStarted");
+                _poll("onBufferingStopped");
+                _poll("onDurationUpdated");
+                _poll("onEnd");
+                _poll("onError");
+                _poll("onVolumeChange");
+                _poll("onClose");
+            }
+            else {
+                _listener = null;
+            }
+
+            return !_closed;
+        },
+
+        close: function () {
+            _listener = null;
+            _closed = true;
+            return transport.call(_uri + "close", {get: {id: _id}});
+        },
+
+        pause: function () {
+            return transport.call(_uri + "pause", {get: {id: _id}});
+        },
+
+        play: function () {
+            return transport.call(_uri + "play", {get: {id: _id}});
+        }
+    };
+
+    _self.__defineGetter__("duration", function () {
+        return transport.call(_uri + "getDuration", {get: {id: _id}});
+    });
+
+    _self.__defineGetter__("mediaTime", function () {
+        return transport.call(_uri + "getMediaTime", {get: {id: _id}});
+    });
+
+    _self.__defineSetter__("mediaTime", function (val) {
+        transport.call(_uri + "setMediaTime", {get: {id: _id, value: val}});
+    });
+
+    _self.__defineGetter__("state", function () {
+        return transport.call(_uri + "getState", {get: {id: _id}});
+    });
+
+    _self.__defineGetter__("volumeLevel", function () {
+        return transport.call(_uri + "getVolumeLevel", {get: {id: _id}});
+    });
+
+    _self.__defineSetter__("volumeLevel", function (val) {
+        transport.call(_uri + "setVolumeLevel", {get: {id: _id, value: val}});
+    });
+
+    _self.__defineGetter__("EVENT_BUFFERING_STARTED", function () {
+        return "EVENT_BUFFERING_STARTED";
+    });
+    _self.__defineGetter__("EVENT_BUFFERING_STOPPED", function () {
+        return "EVENT_BUFFERING_STOPPED";
+    });
+    _self.__defineGetter__("EVENT_CLOSED", function () {
+        return "EVENT_CLOSED";
+    });
+    _self.__defineGetter__("EVENT_DEVICE_AVAILABLE", function () {
+        return "EVENT_DEVICE_AVAILABLE";
+    });
+    _self.__defineGetter__("EVENT_DEVICE_UNAVAILABLE", function () {
+        return "EVENT_DEVICE_UNAVAILABLE";
+    });
+    _self.__defineGetter__("EVENT_DURATION_UPDATED", function () {
+        return "EVENT_DURATION_UPDATED";
+    });
+    _self.__defineGetter__("EVENT_END_OF_MEDIA", function () {
+        return "EVENT_END_OF_MEDIA";
+    });
+    _self.__defineGetter__("EVENT_ERROR", function () {
+        return "EVENT_ERROR";
+    });
+    _self.__defineGetter__("EVENT_RECORD_ERROR", function () {
+        return "EVENT_ERROR";
+    });
+    _self.__defineGetter__("EVENT_RECORD_STARTED", function () {
+        return "EVENT_RECORD_STARTED";
+    });
+    _self.__defineGetter__("EVENT_RECORD_STOPPED", function () {
+        return "EVENT_RECORD_STOPPED";
+    });
+    _self.__defineGetter__("EVENT_SIZE_CHANGED", function () {
+        return "EVENT_SIZE_CHANGED";
+    });
+    _self.__defineGetter__("EVENT_STARTED", function () {
+        return "EVENT_STARTED";
+    });
+    _self.__defineGetter__("EVENT_STOPPED", function () {
+        return "EVENT_STOPPED";
+    });
+    _self.__defineGetter__("EVENT_STOPPED_AT_TIME", function () {
+        return "EVENT_STOPPED_AT_TIME";
+    });
+    _self.__defineGetter__("EVENT_VOLUME_CHANGED", function () {
+        return "EVENT_VOLUME_CHANGED";
+    });
+
+    return _self;
+}
+
+Player.__defineGetter__("TIME_UNKNOWN", function () {
+    return -1;
+});
+Player.__defineGetter__("CLOSED", function () {
+    return 0;
+});
+Player.__defineGetter__("UNREALIZED", function () {
+    return 100;
+});
+Player.__defineGetter__("REALIZED", function () {
+    return 200;
+});
+Player.__defineGetter__("PREFETCHED", function () {
+    return 300;
+});
+Player.__defineGetter__("STARTED", function () {
+    return 400;
+});
+
+module.exports = Player;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/menu', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    MenuItem = require('ripple/platform/webworks.handset/2.0.0/client/MenuItem'),
+    utils = require('ripple/utils'),
+    onSelect,
+    _items = {},
+    _uri = "blackberry/ui/menu/",
+    _self;
+
+_self = {
+    addMenuItem: function (menuItem) {
+        _items[menuItem.id] = menuItem;
+
+        transport.call(_uri + "addMenuItem", {
+            get: {"item": menuItem}
+        });
+
+        if (utils.count(_items) === 1) {
+            transport.poll(_uri + "onSelect", {}, function (response) {
+                var item = _items[response];
+
+                if (item && item.callback) {
+                    item.callback();
+                }
+
+                return !!utils.count(_items);
+            });
+        }
+    },
+
+    clearMenuItems: function () {
+        _items = {};
+        transport.call(_uri + "clearMenuItems");
+    },
+
+    getMenuItems: function () {
+        return utils.map(_items, function (item) {
+            var menuItem = new MenuItem(item.isSeparator, item.ordinal, item.caption, item.callback);
+            menuItem.id = item.id;
+            menuItem.isDefault = item.isDefault;
+            return menuItem;
+        });
+    },
+
+    hasMenuItem: function (menuItem) {
+        return !!_items[menuItem.id];
+    },
+
+    open: function () {
+        transport.call(_uri + "open", {async: true});
+    },
+
+    removeMenuItem: function (menuItem) {
+        delete _items[menuItem.id];
+        transport.call(_uri + "removeMenuItem", {
+            get: {item: menuItem}
+        });
+    },
+
+    setDefaultMenuItem: function (menuItem) {
+        utils.forEach(_items, function (item) {
+            item.isDefault = false;
+        });
+
+        _items[menuItem.id].isDefault = true;
+
+        transport.call(_uri + "setDefaultMenuItem", {
+            get: {id: menuItem.id}
+        });
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/identity', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/identity/",
+    _self;
+
+_self = {
+    getDefaultService: function () {
+        return transport.call(_uri + "getDefaultService");
+    },
+    getServiceList: function () {
+        return transport.call(_uri + "getServiceList");
+    },
+    getTransportList: function () {
+        return transport.call(_uri + "getTransportList");
+    }
+};
+
+_self.__defineGetter__("IMEI", function () {
+    return transport.call(_uri + "IMEI");
+});
+
+_self.__defineGetter__("IMSI", function () {
+    return transport.call(_uri + "IMSI");
+});
+
+_self.__defineGetter__("PIN", function () {
+    return transport.call(_uri + "PIN");
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/messaging', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/CalendarArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.CalendarArguments ( )
+//blackberry.invoke.CalendarArguments ( date : Date )
+//blackberry.invoke.CalendarArguments ( appointment : blackberry.pim.Appointment )
+var _self = function () {
+    //readonly  property  Appointment   appointment
+    //readonly  property  Date   date
+    //readwrite  property  Number   view
+    return {
+        appointment: undefined,
+        date: undefined,
+        view: 0
+    };
+};
+
+//const Number  VIEW_NEW  = 0
+_self.__defineGetter__("VIEW_NEW", function () {
+    return 0;
+});
+//const Number  VIEW_VIEW  = 1
+_self.__defineGetter__("VIEW_VIEW", function () {
+    return 1;
+});
+//const Number  VIEW_AGENDA  = 2
+_self.__defineGetter__("VIEW_AGENDA", function () {
+    return 2;
+});
+//const Number  VIEW_DAY  = 3
+_self.__defineGetter__("VIEW_DAY", function () {
+    return 3;
+});
+//const Number  VIEW_DEFAULT  = 4
+_self.__defineGetter__("VIEW_DEFAULT", function () {
+    return 4;
+});
+//const Number  VIEW_MONTH  = 5
+_self.__defineGetter__("VIEW_MONTH", function () {
+    return 5;
+});
+//const Number  VIEW_WEEK  = 6
+_self.__defineGetter__("VIEW_WEEK", function () {
+    return 6;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/CameraArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.CameraArguments ( )
+var _self = function () {
+    return {
+        //readwrite  property  Number   view
+        view: 0
+    };
+};
+
+//const Number  VIEW_CAMERA  = 0
+_self.__defineGetter__("VIEW_CAMERA", function () {
+    return 0;
+});
+//const Number  VIEW_RECORDER  = 1
+_self.__defineGetter__("VIEW_RECORDER", function () {
+    return 1;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/PushData', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function PushData(data, port) {
+    this.port = port;
+    this.data = data;
+
+    this.getHeaderField = function (field) {
+        if (field === undefined || field === null) {
+            throw "no field specified";
+        }
+        else if (!(typeof field === 'number' && field >= 0) && typeof field !== 'string') {
+            throw "field is not valid";
+        }
+
+        return data.headerField[field];
+    };
+
+    this.getRequestURI =  function () {
+        return data.requestURI;
+    };
+
+    this.getSource = function () {
+        return data.source;
+    };
+
+    this.isChannelEncrypted = data.isChannelEncrypted;
+
+    this.payload = data.payload;
+
+    this.__defineGetter__("ACCEPT", function () {
+        return 0;
+    });
+    this.__defineGetter__("DECLINE_USERDCR", function () {
+        return 1;
+    });
+    this.__defineGetter__("DECLINE_USERDCU", function () {
+        return 2;
+    });
+    this.__defineGetter__("DECLINE_USERPND", function () {
+        return 3;
+    });
+    this.__defineGetter__("DECLINE_USERREQ", function () {
+        return 4;
+    });
+    this.__defineGetter__("DECLINE_USERRFS", function () {
+        return 5;
+    });
+}
+
+module.exports = PushData;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/identity/phone', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/identity/phone/",
+    _self;
+
+_self = {
+    getLineIds: function () {
+        return transport.call(_uri + "getLineIds");
+    },
+    getLineLabel: function (id) {
+        return transport.call(_uri + "getLineLabel", {get: {id: id}});
+    },
+    getLineNumber: function (id) {
+        return transport.call(_uri + "getLineNumber", {get: {id: id}});
+    },
+    getLineType: function (id) {
+        return transport.call(_uri + "getLineType", {get: {id: id}});
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/identity/Service', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function Service() {
+    return {
+        emailAddress: null,
+        isDefault: null,
+        name: null,
+        type: null
+    };
+}
+
+Service.__defineGetter__("TYPE_EMAIL", function () {
+    return 0;
+});
+
+Service.__defineGetter__("TYPE_CALENDAR", function () {
+    return 1;
+});
+
+Service.__defineGetter__("TYPE_CONTACT", function () {
+    return 2;
+});
+
+module.exports = Service;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/identity/Transport', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function Transport(name, type) {
+    this.__defineGetter__("name", function () {
+        return name || "";
+    });
+    this.__defineGetter__("type", function () {
+        return type || "";
+    });
+}
+
+module.exports = Transport;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/Reminder', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var Reminder = function () {
+
+    return {
+        //readwrite  property  Date   date
+        //readwrite  property  Number   relativeHours
+        //readwrite  property  Number   type
+
+        date: null,
+        relativeHours: null,
+        type: null
+
+    };
+
+};
+
+Reminder.__defineGetter__("DATE", function () {
+    return 0;
+});
+
+Reminder.__defineGetter__("RELATIVE", function () {
+    return 1;
+});
+
+module.exports = Reminder;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/systemEvent', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    utils = require('ripple/utils'),
+    _self,
+       _callbacks = {};
+
+function _poll(evt, args, callback) {
+    _callbacks[evt + args.key] = callback;
+
+    transport.poll("blackberry/system/event/" + evt, {get: args}, function () {
+        var func = _callbacks[evt + args.key];
+
+        if (func) {
+            func();
+        }
+
+        return !!func;
+    });
+}
+
+_self = {
+    onCoverageChange: function (callback) {
+        _poll("onCoverageChange", {}, callback);
+    },
+
+    onHardwareKey: function (key, callback) {
+        _poll("onHardwareKey", {key: key}, callback);
+    }
+};
+
+_self.__defineGetter__("KEY_BACK", function () {
+    return 0;
+});
+_self.__defineGetter__("KEY_MENU", function () {
+    return 1;
+});
+_self.__defineGetter__("KEY_CONVENIENCE_1", function () {
+    return 2;
+});
+_self.__defineGetter__("KEY_CONVENIENCE_2", function () {
+    return 3;
+});
+_self.__defineGetter__("KEY_STARTCALL", function () {
+    return 4;
+});
+_self.__defineGetter__("KEY_ENDCALL", function () {
+    return 5;
+});
+_self.__defineGetter__("KEY_VOLUMEDOWN", function () {
+    return 6;
+});
+_self.__defineGetter__("KEY_VOLUMEUP", function () {
+    return 7;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/Attendee', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function Attendee() {
+    return {
+        //readwrite  property  String   address
+        //readwrite  property  Number   type
+
+        address: null,
+        type: null
+    };
+}
+
+Attendee.__defineGetter__("ORGANIZER", function () {
+    return 0;
+});
+
+Attendee.__defineGetter__("INVITED", function () {
+    return 1;
+});
+
+Attendee.__defineGetter__("ACCEPTED", function () {
+    return 2;
+});
+
+Attendee.__defineGetter__("DECLINED", function () {
+    return 3;
+});
+
+Attendee.__defineGetter__("TENTATIVE", function () {
+    return 4;
+});
+
+module.exports =  Attendee;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/audio', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    supportedContentTypes: function (protocol) {
+        return protocol === 'rtsp' ?
+            ['audio/amr', 'audio/mp4', 'audio/aac'] :
+            ['audio/midi', 'mpeg', 'x-wav', 'amr', 'basic', 'x-gsm', 'mp4', 'aac', 'x-ms-wma', 'flac', 'ogg'];
+    },
+    supportedProtocols: function (contentType) {
+        return ['http', 'file', 'rtsp'];
+    }
+};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/category', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/pim/category/",
+    _self;
+
+_self = {
+    addCategory: function (categoryName) {
+        transport.call(_uri + "addCategory", {
+            get: {categoryName: categoryName}
+        });
+    },
+    deleteCategory: function (categoryName) {
+        transport.call(_uri + "deleteCategory", {
+            get: {categoryName: categoryName}
+        });
+    },
+    getCategories: function () {
+        return transport.call(_uri + "getCategories");
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/client/PhoneArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.PhoneArguments ( [dialString : String ] ,  [smartDialing : Boolean ] ,  [lineId : Number ] )
+var _self = function (dialString, smartDialing, lineId) {
+    return {
+        dialString: dialString,
+        smartDialing: smartDialing,
+        lineId: (lineId ? lineId : -1),
+        view: 0
+    };
+};
+
+//const Number  VIEW_NEW  = 0
+_self.__defineGetter__("VIEW_CALL", function () {
+    return 0;
+});
+//const Number  VIEW_DEFAULT  = 1
+_self.__defineGetter__("VIEW_VOICEMAIL", function () {
+    return 1;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/spec/events', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    events = require('ripple/platform/webworks.core/2.0.0/spec/events');
+
+_self = {
+    "system.event.onCoverageChange": {
+        callback: function () {
+            event.trigger("CoverageChange");
+        }
+    },
+    "system.event.onHardwareKey": {
+        args: [
+            "Back",
+            "Menu",
+            "Convenience 1",
+            "Convenience 2",
+            "Start Call",
+            "End Call",
+            "Volume Down",
+            "Volume Up"
+        ],
+        callback: function (key) {
+            event.trigger("HardwareKey", [key]);
+        }
+    }
+};
+
+utils.mixin(events, _self);
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/spec/device', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event');
+
+module.exports = {
+    "transports": {
+        "TCP Cellular": {
+            "name": "Cellular TCP",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        },
+        "Wap": {
+            "name": "WAP",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            }
+        },
+        "Wap 2.0": {
+            "name": "WAP 2.0",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            }
+        },
+        "MDS": {
+            "name": "MDS",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        },
+        "Bis B": {
+            "name": "BIS B",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        },
+        "Unite!": {
+            "name": "Unite",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            }
+        },
+        "TCP Wifi": {
+            "name": "Wifi TCP",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        }
+    },
+    "identity": {
+        "IMEI": {
+            "name": "IMEI",
+            "control": {
+                "type": "text",
+                "value": "123456786543210"
+            }
+        },
+        "IMSI": {
+            "name": "IMSI",
+            "control": {
+                "type": "text",
+                "value": "310150123456789"
+            }
+        },
+        "PIN": {
+            "name": "PIN",
+            "control": {
+                "type": "text",
+                "value": "43A8C489"
+            }
+        }
+    },
+    "system": {
+        "isMassStorageActive": {
+            "name": "Mass Storage Is Connected",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        },
+        "hasDataCoverage": {
+            "name": "Has Data Coverage",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "callback": function (setting) {
+                event.trigger("CoverageChange");
+            }
+        },
+        "network": {
+            "name": "Data Network",
+            "control": {
+                "type": "select",
+                "value": "3GPP"
+            },
+            "options": {
+                "3GPP" : "3GPP",
+                "CDMA": "CDMA",
+                "iDEN": "iDEN",
+                "Wi-Fi": "Wi-Fi"
+            },
+            "callback": function (setting) {
+                event.trigger("CoverageChange");
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/spec/ui', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    plugins: [
+        "accelerometer",
+        "deviceSettings",
+        "geoView",
+        "platformEvents",
+        "widgetConfig",
+        "messaging",
+        "push",
+        "phone"
+    ]
+};
+
+});
+require.define('ripple/platform/webworks.handset/2.0.0/spec', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    id: "webworks.handset",
+    version: "2.0.0",
+    name: "WebWorks",
+
+    persistencePrefix: "rim-handset-",
+
+    ui: require('ripple/platform/webworks.handset/2.0.0/spec/ui'),
+    device: require('ripple/platform/webworks.handset/2.0.0/spec/device'),
+    config: require('ripple/platform/webworks.core/2.0.0/spec/config'),
+    events: require('ripple/platform/webworks.handset/2.0.0/spec/events'),
+
+    objects: {
+        XMLHttpRequest: {
+            path: "webworks.handset/2.0.0/XMLHttpRequest"
+        },
+        Coordinates: {
+            path: "w3c/1.0/Coordinates"
+        },
+        Position: {
+            path: "w3c/1.0/Position"
+        },
+        PositionError: {
+            path: "w3c/1.0/PositionError"
+        },
+        navigator: {
+            path: "w3c/1.0/navigator",
+            children: {
+                geolocation: {
+                    path: "w3c/1.0/geolocation"
+                }
+            }
+        },
+        blackberry: {
+            path: "webworks.handset/2.0.0/client/blackberry",
+            children: {
+                pim: {
+                    path: "webworks.handset/2.0.0/client/pim",
+                    feature: "blackberry.pim.category|blackberry.pim.Task|blackberry.pim.Recurrence|blackberry.pim.Reminder|blackberry.pim.Appointment|blackberry.pim.Address|blackberry.pim.Attendee|blackberry.pim.Memo|blackberry.pim.Contact",
+                    children: {
+                        category: {
+                            path: "webworks.handset/2.0.0/client/category",
+                            feature: "blackberry.pim.category"
+                        },
+                        Task: {
+                            path: "webworks.handset/2.0.0/client/Task",
+                            feature: "blackberry.pim.Task"
+                        },
+                        Recurrence: {
+                            path: "webworks.handset/2.0.0/client/Recurrence",
+                            feature: "blackberry.pim.Recurrence"
+                        },
+                        Reminder: {
+                            path: "webworks.handset/2.0.0/client/Reminder",
+                            feature: "blackberry.pim.Reminder"
+                        },
+                        Appointment: {
+                            path: "webworks.handset/2.0.0/client/Appointment",
+                            feature: "blackberry.pim.Appointment"
+                        },
+                        Address: {
+                            path: "webworks.handset/2.0.0/client/Address",
+                            feature: "blackberry.pim.Address"
+                        },
+                        Attendee: {
+                            path: "webworks.handset/2.0.0/client/Attendee",
+                            feature: "blackberry.pim.Attendee"
+                        },
+                        Memo: {
+                            path: "webworks.handset/2.0.0/client/Memo",
+                            feature: "blackberry.pim.Memo"
+                        },
+                        Contact: {
+                            path: "webworks.handset/2.0.0/client/Contact",
+                            feature: "blackberry.pim.Contact"
+                        }
+                    }
+                },
+                phone: {
+                    children: {
+                        Phone: {
+                            path: "webworks.handset/2.0.0/client/Phone",
+                            feature: "blackberry.phone.Phone"
+                        },
+                        PhoneLogs: {
+                            path: "webworks.handset/2.0.0/client/PhoneLogs",
+                            feature: "blackberry.phone.PhoneLogs|blackberry.phone.Find",
+                            children: {
+                                CallLog: {
+                                    path: "webworks.handset/2.0.0/client/CallLog"
+                                }
+                            }
+                        },
+                        Find: {
+                            children: {
+                                FilterExpression: {
+                                    path: "webworks.handset/2.0.0/client/FilterExpression",
+                                    feature: "blackberry.phone.Find"
+                                }
+                            }
+                        }
+                    }
+                },
+                message: {
+                    path: "webworks.handset/2.0.0/client/messaging",
+                    feature: "blackberry.message.sms|blackberry.message",
+                    children: {
+                        sms: {
+                            path: "webworks.handset/2.0.0/client/sms",
+                            feature: "blackberry.message.sms"
+                        },
+                        Message: {
+                            path: "webworks.handset/2.0.0/client/Message",
+                            feature: "blackberry.message"
+                        }
+                    }
+                },
+                transport: {
+                    path: "webworks.core/2.0.0/client/transport"
+                },
+                events: {
+                    path: "webworks.core/2.0.0/client/events"
+                },
+                app: {
+                    path: "webworks.handset/2.0.0/client/app",
+                    feature: "blackberry.app",
+                    children: {
+                        event: {
+                            path: "webworks.handset/2.0.0/client/appEvent",
+                            feature: "blackberry.app.event"
+                        }
+                    }
+                },
+                invoke: {
+                    path: "webworks.handset/2.0.0/client/invoke",
+                    feature: "blackberry.invoke",
+                    children: {
+                        AddressBookArguments: {
+                            path: "webworks.handset/2.0.0/client/AddressBookArguments",
+                            feature: "blackberry.invoke.AddressBookArguments"
+                        },
+                        BrowserArguments: {
+                            path: "webworks.handset/2.0.0/client/BrowserArguments",
+                            feature: "blackberry.invoke.BrowserArguments"
+                        },
+                        CameraArguments: {
+                            path: "webworks.handset/2.0.0/client/CameraArguments",
+                            feature: "blackberry.invoke.CameraArguments"
+                        },
+                        CalendarArguments: {
+                            path: "webworks.handset/2.0.0/client/CalendarArguments",
+                            feature: "blackberry.invoke.CalendarArguments"
+                        },
+                        JavaArguments: {
+                            path: "webworks.handset/2.0.0/client/JavaArguments",
+                            feature: "blackberry.invoke.JavaArguments"
+                        },
+                        MapsArguments: {
+                            path: "webworks.handset/2.0.0/client/MapsArguments",
+                            feature: "blackberry.invoke.MapsArguments"
+                        },
+                        MemoArguments: {
+                            path: "webworks.handset/2.0.0/client/MemoArguments",
+                            feature: "blackberry.invoke.MemoArguments"
+                        },
+                        MessageArguments: {
+                            path: "webworks.handset/2.0.0/client/MessageArguments",
+                            feature: "blackberry.invoke.MessageArguments"
+                        },
+                        PhoneArguments: {
+                            path: "webworks.handset/2.0.0/client/PhoneArguments",
+                            feature: "blackberry.invoke.PhoneArguments"
+                        },
+                        SearchArguments: {
+                            path: "webworks.handset/2.0.0/client/SearchArguments",
+                            feature: "blackberry.invoke.SearchArguments"
+                        },
+                        TaskArguments: {
+                            path: "webworks.handset/2.0.0/client/TaskArguments",
+                            feature: "blackberry.invoke.TaskArguments"
+                        }
+                    }
+                },
+                identity: {
+                    path: "webworks.handset/2.0.0/client/identity",
+                    feature: "blackberry.identity",
+                    children: {
+                        Transport: {
+                            path: "webworks.handset/2.0.0/client/identity/Transport",
+                            feature: "blackberry.identity"
+                        },
+                        Service: {
+                            path: "webworks.handset/2.0.0/client/identity/Service",
+                            feature: "blackberry.identity"
+                        },
+                        phone: {
+                            path: "webworks.handset/2.0.0/client/identity/phone",
+                            feature: "blackberry.identity.phone"
+                        }
+                    }
+                },
+                system: {
+                    path: "webworks.handset/2.0.0/client/system",
+                    feature: "blackberry.system",
+                    children: {
+                        event: {
+                            path: "webworks.handset/2.0.0/client/systemEvent",
+                            feature: "blackberry.system.event"
+                        }
+                    }
+                },
+                ui: {
+                    children: {
+                        dialog: {
+                            path: "webworks.handset/2.0.0/client/dialog",
+                            feature: "blackberry.ui.dialog"
+                        },
+                        menu: {
+                            path: "webworks.handset/2.0.0/client/menu",
+                            children: {
+                                MenuItem: {
+                                    path: "webworks.handset/2.0.0/client/MenuItem"
+                                }
+                            }
+                        }
+                    }
+                },
+                utils: {
+                    path: "webworks.core/2.0.0/client/utils",
+                    feature: "blackberry.utils"
+                },
+                find: {
+                    feature: "blackberry.find",
+                    children: {
+                        FilterExpression: {
+                            path: "webworks.handset/2.0.0/client/FilterExpression",
+                            feature: "blackberry.find"
+                        }
+                    }
+                },
+                push: {
+                    path: "webworks.handset/2.0.0/client/push",
+                    feature: "blackberry.push"
+                },
+                audio: {
+                    path: "webworks.handset/2.0.0/client/audio",
+                    feature: "blackberry.audio",
+                    children: {
+                        Player: {
+                            path: "webworks.handset/2.0.0/client/AudioPlayer",
+                            feature: "blackberry.audio.Player"
+                        }
+                    }
+                },
+                io: {
+                    children: {
+                        dir: {
+                            path: "webworks.handset/2.0.0/client/io/dir",
+                            feature: "blackberry.io.dir"
+                        },
+                        file: {
+                            path: "webworks.core/2.0.0/client/io/file",
+                            feature: "blackberry.io.file"
+                        }
+                    }
+                }
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/AudioCodecAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (info, id, compFormats, encode, decode) {
+    return {
+        info: info,
+        id: id,
+        compFormats: compFormats,
+        encode: encode,
+        decode: decode
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/DisplayDeviceAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (orientation, brightness, contrast, blanked, dotsPerInchW, dotsPerInchH, physicalWidth, physicalHeight, info) {
+    return {
+        orientation: orientation,
+        brightness: brightness,
+        contrast: contrast,
+        blanked: blanked,
+        dotsPerInchW: dotsPerInchW,
+        dotsPerInchH: dotsPerInchH,
+        physicalWidth: physicalWidth,
+        physicalHeight: physicalHeight,
+        info: info
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/StorageUnitAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (info, id, type, isWritable, capacity, availableCapacity, isRemoveable) {
+    return {
+        info: info,
+        id: id,
+        type: type,
+        isWritable: isWritable,
+        capacity: capacity,
+        availableCapacity: availableCapacity,
+        isRemoveable: isRemoveable
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/orientation', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    currentOrientation: null,
+    getCurrentOrientation: function (onSuccess, onFail) {
+        throw "not implemented";
+    },
+    watchOrientation: function () {
+        throw "not implemented";
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/InputDevicesAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (info, id, pointingDevices, activePointingDevices, keyboards, activeKeyboards, cameras, activeCameras, microphones, activeMicrophones) {
+    return {
+        info: info,
+        id: id,
+        pointingDevices: pointingDevices,
+        activePointingDevices: activePointingDevices,
+        keyboards: keyboards,
+        activeKeyboards: activeKeyboards,
+        cameras: cameras,
+        activeCameras: activeCameras,
+        microphones: microphones,
+        activeMicrophones: activeMicrophones
+    };
+
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/ContactAddress', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (pref, type, formatted, streetAddress, locality, region, postalCode, country, id) {
+    return {
+        pref: pref || null,
+        type: type || null,
+        formatted: formatted || null,
+        streetAddress: streetAddress || null,
+        locality: locality || null,
+        region: region || null,
+        postalCode: postalCode || null,
+        country: country || null,
+        id: id || null
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/telephony', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    send: function () {
+        throw "not implemented";
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/PowerAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (info, id, level, timeRemaining, isBattery, isCharging) {
+    return {
+        info: info,
+        id: id,
+        level: level,
+        timeRemaining: timeRemaining,
+        isBattery: isBattery,
+        isCharging: isCharging
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/ContactError', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function ContactError(code) {
+    this.code = code || null;
+}
+
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
+ContactError.NOT_FOUND_ERROR = 2;
+ContactError.TIMEOUT_ERROR = 3;
+ContactError.PENDING_OPERATION_ERROR = 4;
+ContactError.IO_ERROR = 5;
+ContactError.NOT_SUPPORTED_ERROR = 6;
+ContactError.PERMISSION_DENIED_ERROR = 20;
+
+module.exports = ContactError;
+
+});
+require.define('ripple/platform/phonegap/1.0/ThermalAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (info, id, state) {
+    return {
+        info: info,
+        id: id,
+        state: state
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/MicrophoneAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (type, freqRangeLow, freqRangeHigh, info, name, types) {
+    return {
+        type: type,
+        freqRangeLow: freqRangeLow,
+        freqRangeHigh: freqRangeHigh,
+        info: info,
+        name: name,
+        types: types
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/map', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    show: function () {
+        throw "not implemented";
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/ContactAccount', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (domain, username, userid) {
+    return {
+        domain: domain,
+        username: username,
+        userid: userid
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/accelerometer', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var Acceleration = require('ripple/platform/phonegap/1.0/Acceleration'),
+    utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    _accelerometerInfo = new Acceleration(),
+    _watches = {},
+    self;
+
+module.exports = self = {
+    getCurrentAcceleration: function (onSuccess, onError) {
+        // TODO: implement error call if accelerometer is not available, to be driven by behaviours?
+
+        if (typeof onSuccess === "function") {
+            setTimeout(function () {
+                // TODO: build facility to trigger onError() from emulator
+                // see pivotal item: https://www.pivotaltracker.com/story/show/7040343
+                onSuccess(utils.copy(_accelerometerInfo));
+            }, 1);
+        }
+
+    },
+
+    watchAcceleration: function (accelerometerSuccess, accelerometerError, accelerometerOptions) {
+        var watchId = (new Date()).getTime().toString(),
+            watchObj = {};
+
+
+        if (accelerometerOptions &&
+                accelerometerOptions.frequency && typeof
+                accelerometerOptions.frequency === "number" &&
+                accelerometerOptions.frequency === Math.floor(accelerometerOptions.frequency)) {
+
+            watchObj = {
+                onSuccess: accelerometerSuccess,
+                onError: accelerometerError,
+                interval: accelerometerOptions.frequency
+            };
+
+            _watches[watchId] = watchObj;
+
+            _watches[watchId].intervalId = setInterval(function () {
+                self.getCurrentAcceleration(_watches[watchId].onSuccess, _watches[watchId].onError);
+            }, accelerometerOptions.frequency);
+
+        }
+        else {
+            if (typeof accelerometerError === "function") {
+                setTimeout(function () {
+                    accelerometerError();
+                }, 1);
+            }
+        }
+
+        return watchId;
+    },
+
+    clearWatch: function (watchId) {
+        clearInterval(_watches[watchId].intervalId);
+    }
+};
+
+event.on("AccelerometerInfoChangedEvent", function (accelerometerInfo) {
+    _accelerometerInfo.x = accelerometerInfo.accelerationIncludingGravity.x / 9.8;
+    _accelerometerInfo.y = accelerometerInfo.accelerationIncludingGravity.y / 9.8;
+    _accelerometerInfo.z = accelerometerInfo.accelerationIncludingGravity.z / 9.8;
+    _accelerometerInfo.timestamp = (new Date()).getTime();
+});
+
+});
+require.define('ripple/platform/phonegap/1.0/PointerAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (type, supportsMultiTouch, info) {
+    return {
+        type: type,
+        supportsMultiTouch: supportsMultiTouch,
+        info: info
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/PrintingDeviceAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (type, resolution, color, info) {
+    return {
+        type: type,
+        resolution: resolution,
+        color: color,
+        info: info
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/NetworkStatus', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    NOT_REACHABLE: 0,
+    REACHABLE_VIA_CARRIER_DATA_NETWORK: 1,
+    REACHABLE_VIA_WIFI_NETWORK: 2
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/SystemInfoOptions', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (highThreshold, lowThreshold, thresholdTarget, timeout, id) {
+    return {
+        highThreshold: highThreshold,
+        lowThreshold: lowThreshold,
+        thresholdTarget: thresholdTarget,
+        timeout: timeout,
+        id: id
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/ConnectionAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (info, id, type, currentOrientation, currentUploadBandwidth, maxDownloadBandwidth, maxUploadBandwidth, currentSignalStrength, roaming) {
+    return {
+        info: info,
+        id: id,
+        type: type,
+        currentDownloadBandwidth: currentOrientation,
+        currentUploadBandwidth: currentUploadBandwidth,
+        maxDownloadBandwidth: maxDownloadBandwidth,
+        maxUploadBandwidth: maxUploadBandwidth,
+        currentSignalStrength: currentSignalStrength,
+        roaming: roaming
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/ContactName', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (formatted, familyName, givenName, middleName, honorificPrefix, honorificSuffix) {
+    return {
+        formatted: formatted,
+        familyName: familyName,
+        givenName: givenName,
+        middleName: middleName,
+        honorificPrefix: honorificPrefix,
+        honorificSuffix: honorificSuffix
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/KeyboardAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (type, isHardware, info) {
+    return {
+        type: type,
+        isHardware: isHardware,
+        info: info
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/CameraAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (supportsVideo, hasFlash, sensorPixels, maxZoomFactor) {
+    return {
+        supportsVideo: supportsVideo,
+        hasFlash: hasFlash,
+        sensorPixels: sensorPixels,
+        maxZoomFactor: maxZoomFactor
+    };
+
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/Connection', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    UNKNOWN: "unknown",
+    ETHERNET: "ethernet",
+    WIFI: "wifi",
+    CELL_2G: "2g",
+    CELL_3G: "3g",
+    CELL_4G: "4g",
+    NONE: "none"
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/Contact', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    event = require('ripple/event');
+
+function _properties(obj) {
+    var prop, newObj = {};
+    for (prop in obj) {
+        if (Object.prototype.hasOwnProperty.call(obj, prop)) {
+            if (typeof obj[prop] !== "function") {
+                newObj[prop] = utils.copy(obj[prop]);
+            }
+        }
+    }
+    return newObj;
+}
+
+module.exports = function (
+        id,
+        displayName,
+        name,
+        nickname,
+        phoneNumbers,
+        emails,
+        addresses,
+        ims,
+        organizations,
+        birthday,
+        note,
+        photos,
+        categories,
+        urls
+) {
+
+    return {
+        id: id || Math.uuid(undefined, 16),
+        displayName: displayName || null,
+        name: name || null,
+        nickname: nickname || null,
+        phoneNumbers: phoneNumbers || null,
+        emails: emails || null,
+        addresses: addresses || null,
+        ims: ims || null,
+        organizations: organizations || null,
+        birthday: birthday || null,
+        note: note || null,
+        photos: photos || null,
+        categories: categories || null,
+        urls: urls || null,
+        save: function (success, error) {
+            var _self = this,
+                lastUpdated = this.updated; // hackish
+
+            this.updated = new Date();
+
+            if (!this.id) {
+                this.id = Math.uuid(undefined, 16);
+            }
+
+            event.trigger("phonegap-contact-save", [_properties(this), success, function (e) {
+                _self.updated = lastUpdated;
+                error(e);
+            }]);
+        },
+        remove: function (success, error) {
+            event.trigger("phonegap-contact-remove", [this.id, success, error]);
+        },
+        clone: function () {
+            var copy = utils.copy(this);
+            copy.id = null;
+            return copy;
+        }
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/device', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self = {},
+    event = require('ripple/event'),
+    devices = require('ripple/devices');
+
+
+event.on("HardwareKey", function (key) {
+    event.trigger("HardwareKeyDefault", [key]);
+});
+
+_self.__defineGetter__("name", function () {
+    return devices.getCurrentDevice().name;
+});
+
+_self.__defineGetter__("platform", function () {
+    return devices.getCurrentDevice().osName;
+});
+
+_self.__defineGetter__("uuid", function () {
+    return devices.getCurrentDevice().uuid;
+});
+
+_self.__defineGetter__("version", function () {
+    return devices.getCurrentDevice().osVersion;
+});
+
+_self.phonegap = "placeholder string";
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/phonegap/1.0/sms', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    send: function () {
+        throw "not implemented";
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/navigator', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var nav = require('ripple/platform/w3c/1.0/navigator'),
+    event = require('ripple/event'),
+    _console = require('ripple/console'),
+    utils = require('ripple/utils'),
+    emulatorBridge = require('ripple/emulatorBridge'),
+    _self = {};
+
+event.on("TinyHipposLoaded", function () {
+    var doc = emulatorBridge.document(),
+        evt = doc.createEvent("Events");
+    evt.initEvent("deviceready", true, true);
+    doc.dispatchEvent(evt);
+    _console.log("fired deviceready event!");
+});
+
+utils.mixin(nav, _self);
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/phonegap/1.0/NetworkAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (info, id, activeConnections) {
+    return {
+        info: info,
+        id: id,
+        activeConnections: activeConnections || []
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/AVCodecsAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (info, id, audioCodecs, videoCodecs) {
+    return {
+        info: info,
+        id: id,
+        audioCodecs: audioCodecs,
+        videoCodecs: videoCodecs
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/Acceleration', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (x, y, z) {
+    return {
+        x: x || 0,
+        y: y || 0,
+        z: z || 0,
+        timestamp: new Date().getTime()
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/ContactField', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (type, value, pref) {
+    return {
+        type: type,
+        value: value,
+        pref: pref || false
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/system', function (require, module, exports) {
+module.exports = {
+    get: function () {
+        throw "not implemented";
+    },
+    has: function () {
+        throw "not implemented";
+    },
+    monitor: function () {
+        throw "not implemented";
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/OutputDevicesAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (info, id, displayDevices, activeDisplayDevices, printingDevices, activePrintingDevice, brailleDevices, activeBrailleDevice, audioDevices, activeAudioDevices) {
+    return {
+        info: info,
+        id: id,
+        displayDevices: displayDevices,
+        activeDisplayDevices: activeDisplayDevices,
+        printingDevices: printingDevices,
+        activePrintingDevice: activePrintingDevice,
+        brailleDevices: brailleDevices,
+        activeBrailleDevice: activeBrailleDevice,
+        audioDevices: audioDevices,
+        activeAudioDevices: activeAudioDevices
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/PhoneGap', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    available: true
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/ContactFindOptions', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (filter, multiple, updatedSince) {
+    return {
+        filter: filter || "",
+        multiple: multiple || false,
+        updatedSince: updatedSince || ""
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/camera', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    getPicture: function (cameraSuccess, cameraError, cameraOptions) {
+        if (cameraError) {
+            cameraError.apply(null, ["not implemented"]);
+        }
+        else {
+            throw "not implemented";
+        }
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/BrailleDeviceAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (nbCells, info) {
+    return {
+        nbCells: nbCells,
+        info: info
+    };
+
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/service', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// for form, but could probably just delete
+module.exports = {};
+
+});
+require.define('ripple/platform/phonegap/1.0/AudioDeviceAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (type, freqRangeLow, freqRangeHigh, volumeLevel, info) {
+    return {
+        type: type,
+        freqRangeLow: freqRangeLow,
+        freqRangeHigh: freqRangeHigh,
+        volumeLevel: volumeLevel,
+        info: info
+    };
+
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/compass', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var geo = require('ripple/geo');
+
+function _getHeading() {
+    return geo.getPositionInfo().heading;
+}
+
+module.exports = {
+    getCurrentHeading: function (compassSuccess, compassError, compassOptions) {
+        setTimeout(function () {
+            compassSuccess(_getHeading());
+        }, 1);
+    },
+    watchHeading: function (compassSuccess, compassError, compassOptions) {
+        compassOptions = compassOptions || {};
+        return setInterval(function () {
+            compassSuccess(_getHeading());
+        }, compassOptions.frequency || 100);
+    },
+    clearWatch: function (watchId) {
+        clearInterval(watchId);
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/contacts', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var Contact = require('./Contact'),
+    ContactName = require('./ContactName'),
+    ContactError = require('./ContactError'),
+    ContactField = require('./ContactField'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    event = require('ripple/event'),
+    _defaultContacts = 
+    [{
+        "id": Math.uuid(undefined, 16),
+        "name": new ContactName("Brent Lintner"),
+        "displayName": "Brent Lintner",
+        "emails": [new ContactField("work", "brent@tinyhippos.com", false)]
+    }, {
+        "id": Math.uuid(undefined, 16),
+        "name": new ContactName("PJ Lowe"),
+        "displayName": "PJ Lowe",
+        "emails": [new ContactField("work", "pj@tinyhippos.com", false)]
+    }, {
+        "id": Math.uuid(undefined, 16),
+        "name": new ContactName("Dan Silivestru"),
+        "displayName": "Dan Silivestru",
+        "emails": [new ContactField("work", "dan@tinyhippos.com", false)]
+    }, {
+        "id": Math.uuid(undefined, 16),
+        "name": new ContactName("Gord Tanner"),
+        "displayName": "Gord Tanner",
+        "emails": [new ContactField("work", "gord@tinyhippos.com", true)]
+    }, {
+        "id": Math.uuid(undefined, 16),
+        "name": new ContactName("Mark McArdle"),
+        "displayName": "Mark McArdle",
+        "emails": [new ContactField("work", "mark@tinyhippos.com", false)]
+    }],
+    self;
+
+function _error(callback, code, msg) {
+    var e = new ContactError();
+    e.code = code;
+    e.message = msg;
+    window.setTimeout(function () {
+        callback(e);
+    }, 1);
+}
+
+
+function _getContacts() {
+    return db.retrieveObject("phonegap-contacts") || 
+        _defaultContacts.map(function (person) {
+            var contact = new Contact();
+            contact.updated = new Date();
+            utils.forEach(person, function (value, prop) {
+                contact[prop] = value;
+            });
+
+            return contact;
+        });
+}
+
+function _saveContacts(contacts) {
+    db.saveObject("phonegap-contacts", contacts);
+}
+
+function _filtered(compare, options) {
+    // this could be done a lot better..
+    var found = false;
+    if (!options.filter || options.filter === "") {
+        found = true;
+    } else if (typeof compare === "string" &&
+              compare.match(new RegExp(".*" + options.filter + ".*", "i"))) {
+        found = true;
+    } else if (typeof compare === "object" || compare instanceof Array) {
+        utils.forEach(compare, function (value) {
+            if (!found) {
+                found = _filtered(value, options);
+            }
+        });
+    }
+    return found;
+}
+
+event.on("phonegap-contact-save", function (contactProperties, success, error) {
+    var contacts = _getContacts(),
+        existsIndex = contacts.reduce(function (result, value, index) {
+            return value.id === contactProperties.id ? index : result;
+        }, -1),
+        contact = existsIndex >= 0 ? contacts[existsIndex] : new Contact();
+
+    utils.mixin(contactProperties, contact);
+    if (existsIndex < 0) {
+        contacts.push(contact);
+    }
+    _saveContacts(contacts);
+    success(contact);
+});
+
+event.on("phonegap-contact-remove", function (id, success, error) {
+    if (!id) {
+        _error(error, ContactError.NOT_FOUND_ERROR, "id is falsy (" + id + ")");
+    } else {
+        var contacts = _getContacts(),
+            toDelete = contacts.reduce(function (result, current, index) {
+                return current.id === id ? index : result;
+            }, -1);
+
+        if (toDelete >= 0) {
+            contacts.splice(toDelete, 1);
+            _saveContacts(contacts);
+            success();
+        } else {
+            _error(error, ContactError.NOT_FOUND_ERROR, "could not find contact with id (" + id + ")");
+        }
+    }
+});
+
+self = module.exports = {
+    create: function (properties) {
+        var contact = new Contact();
+        utils.forEach(properties, function (value, key) {
+            contact[key] = value;
+        });
+        return contact;
+    },
+    find: function (fields, success, error, options) {
+        var foundContacts = [],
+            tempContact = self.create(),
+            contacts = _getContacts(),
+            errorFlag = false;
+
+        options = options || {};
+
+        // not a fan of error handling at the moment
+        if (!fields || !("forEach" in fields)) {
+            errorFlag = true;
+            _error(error, ContactError.INVALID_ARGUMENT_ERROR, "missing contact fields array");
+            return;
+        }
+
+        // handle special case of ["*"] to return all fields
+        if (fields.length === 1 && fields[0] === "*") {
+            fields = utils.map(tempContact, function (v, k) {
+                return k;
+            });
+        }
+
+        fields.forEach(function (prop) {
+            if (!(tempContact.hasOwnProperty(prop))) {
+                errorFlag = true;
+                _error(error, ContactError.INVALID_ARGUMENT_ERROR, "invalid contact field (" + prop + ")");
+            }
+        });
+
+        if (typeof success !== "function" && !errorFlag) {
+            errorFlag = true;
+            _error(error, ContactError.INVALID_ARGUMENT_ERROR, "missing success callback");
+        }
+
+        if (errorFlag) {
+            return;
+        }
+
+        if (fields.length > 0) {
+            contacts.forEach(function (contact, index) {
+                var newContact = utils.copy(contact);
+
+                if (options && (!_filtered(contact, options) ||
+                        options.updatedSince && contact.updated && contact.updated.getTime() < options.updatedSince.getTime())) {
+                    return;
+                }
+
+                utils.forEach(newContact, function (value, prop) {
+                    if (typeof newContact[prop] !== "function" && prop !== "id" &&
+                        !fields.some(function (field) {
+                            return field === prop;
+                        })) {
+                        delete newContact[prop];
+                    }
+                });
+
+                foundContacts.push(newContact);
+            });
+        }
+
+        window.setTimeout(function () {
+            // TODO: don't loop over entire db just to slice the array
+            if (options.multiple === false) {
+                foundContacts = foundContacts.splice(0, 1);
+            }
+            success(foundContacts);
+        }, 1);
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/CPUAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (info, id, usage) {
+    return {
+        info: info,
+        id: id,
+        usage: usage
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/VideoCodecAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (info, id, compFormats, containerFormats, hwAccel, profiles, frameTypes, rateTypes) {
+    return {
+        info: info,
+        id: id,
+        compFormats: compFormats,
+        containerFormats: containerFormats,
+        hwAccel: hwAccel,
+        profiles: profiles,
+        frameTypes: frameTypes,
+        rateTypes: rateTypes
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/spec/events', function (require, module, exports) {
+function _fires(name, data) {
+    return function () {
+        var doc = require("ripple/emulatorBridge").document(),
+            evt = doc.createEvent("Events");
+
+        evt.initEvent(name, true, false);
+        doc.dispatchEvent(evt);
+    };
+}
+
+module.exports = {
+    "deviceready": {
+        callback: _fires("deviceready")
+    },
+    "backbutton": {
+        callback: _fires("backbutton")
+    },
+    "menubutton": {
+        callback: _fires("menubutton")
+    },
+    "pause": {
+        callback: _fires("pause")
+    },
+    "resume": {
+        callback: _fires("resume")
+    },
+    "searchbutton": {
+        callback: _fires("searchbutton")
+    },
+    "online": {
+        callback: _fires("online")
+    },
+    "offline": {
+        callback: _fires("offline")
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/spec/device', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event');
+
+module.exports = {
+    "NetworkStatus": {
+        "connectionType": {
+            "name": "Connection Type",
+            "control": {
+                "type": "select",
+                "value": "ethernet"
+            },
+            "options": {
+                "unknown": "UNKNOWN",
+                "ethernet": "ETHERNET",
+                "wifi": "WIFI",
+                "2g": "CELL_2G",
+                "3g": "CELL_3G",
+                "4g": "CELL_4G",
+                "none": "none"
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/spec/ui', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    plugins: [
+        "accelerometer",
+        "deviceSettings",
+        "geoView",
+        "widgetConfig",
+        "platformEvents"
+    ]
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/spec/config', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants');
+
+module.exports = {
+    fileName: "config.xml",
+    validateVersion: function (configValidationObject) {
+        var valid = true;
+        valid = !((!configValidationObject.widget.validationResult[0].attributes.xmlns.valid) ||
+            (!configValidationObject.widget.validationResult[0].attributes["xmlns:gap"].valid));
+
+        return valid;
+    },
+    extractInfo: function (configValidationObject) {
+        if (!configValidationObject) {
+            return null;
+        }
+
+        var widgetInfo = {};
+
+        widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
+        widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
+        widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
+        widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
+
+        return widgetInfo;
+    },
+    schema: {
+        rootElement: "widget",
+        widget: {
+            nodeName: "widget",
+            required: true,
+            occurrence: 1,
+            attributes: {
+                xmlns: {
+                    attributeName: "xmlns",
+                    required: true,
+                    type: "list",
+                    listValues: ["http://www.w3.org/ns/widgets"]
+                },
+                "xmlns:gap": {
+                    attributeName: "xmlns:gap",
+                    required: true,
+                    type: "list",
+                    listValues: ["http://phonegap.com/ns/1.0"]
+                },
+                "xml:lang": {
+                    attributeName: "xml:lang",
+                    required: false,
+                    type: "iso-language"
+                },
+                dir: {
+                    attributeName: "dir",
+                    required: false,
+                    type: "list",
+                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                },
+                id: {
+                    attributeName: "id",
+                    required: false,
+                    type: "string"
+                },
+                version: {
+                    attributeName: "version",
+                    required: false,
+                    type: "string"
+                },
+                height: {
+                    attributeName: "height",
+                    required: false,
+                    type: "integer"
+                },
+                width: {
+                    attributeName: "width",
+                    required: false,
+                    type: "integer"
+                },
+                viewmodes: {
+                    attributeName: "viewmodes",
+                    required: false,
+                    type: "list",
+                    listValues: ["floating", "fullscreen"]
+                }
+            },
+            children: {
+                name: {
+                    nodeName: "name",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "short": {
+                            attributeName: "short",
+                            type: "string",
+                            required: false
+                        },
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            type: "string",
+                            required: false,
+                            unique: true
+                        }
+                    }
+                },
+                description: {
+                    nodeName: "description",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            type: "string",
+                            required: false,
+                            unique: true
+                        }
+                    }
+                },
+                author: {
+                    nodeName: "author",
+                    required: false,
+                    occurrence: 1,
+                    type: "string",
+                    attributes: {
+                        email: {
+                            attributeName: "email",
+                            type: "regex",
+                            required: false,
+                            regex: constants.REGEX.EMAIL
+                        },
+                        href: {
+                            attributeName: "href",
+                            type: "regex",
+                            required: false,
+                            regex: constants.REGEX.URL
+                        }
+                    }
+                },
+                license: {
+                    nodeName: "license",
+                    required: false,
+                    occurrence: 1,
+                    type: "string",
+                    attributes: {
+                        href: {
+                            attributeName: "href",
+                            type: "regex",
+                            required: false,
+                            regex: constants.REGEX.URL
+                        },
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            type: "string",
+                            required: false,
+                            unique: true
+                        }
+                    }
+                },
+                icon: {
+                    nodeName: "icon",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        src: {
+                            attributeName: "src",
+                            type: "string",
+                            required: true
+                        },
+                        height: {
+                            attributeName: "height",
+                            required: false,
+                            type: "integer"
+                        },
+                        width: {
+                            attributeName: "width",
+                            required: false,
+                            type: "integer"
+                        }
+                    }
+                },
+                content: {
+                    nodeName: "content",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        src: {
+                            attributeName: "src",
+                            type: "string",
+                            required: true
+                        },
+                        encoding: {
+                            attributeName: "encoding",
+                            type: "string",
+                            required: false
+                        },
+                        type: {
+                            attributeName: "type",
+                            type: "string",
+                            required: false
+                        }
+                    }
+                },
+                feature: {
+                    nodeName: "feature",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        name: {
+                            attributeName: "name",
+                            type: "list",
+                            required: true,
+                            listValues: ["http://api.phonegap.com/1.0/accelerometer", "http://api.phonegap.com/1.0/camera",
+                                "http://api.phonegap.com/1.0/compass", "http://api.phonegap.com/1.0/contacts", "http://api.phonegap.com/1.0/device",
+                                "http://api.phonegap.com/1.0/events", "http://api.phonegap.com/1.0/file", "http://api.phonegap.com/1.0/geolocation",
+                                "http://api.phonegap.com/1.0/media", "http://api.phonegap.com/1.0/network", "http://api.phonegap.com/1.0/notification",
+                                "http://api.phonegap.com/1.0/storage"]
+                        },
+                        required: {
+                            attributeName: "required",
+                            type: "boolean",
+                            required: false
+                        }
+                    }
+                },
+                preference: {
+                    nodeName: "preference",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        name: {
+                            attributeName: "name",
+                            type: "string",
+                            required: true
+                        },
+                        value: {
+                            type: "string",
+                            attributeName: "value",
+                            required: false
+                        },
+                        readonly: {
+                            attributeName: "readonly",
+                            type: "boolean",
+                            required: false
+                        }
+                    }
+                }
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/ContactOrganization', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (pref, type, name, dept, title) {
+    return {
+        pref: pref || null,
+        type: type || null,
+        name: name || null,
+        department: dept || null,
+        title: title || null
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/spec', function (require, module, exports) {
+module.exports = {
+    id: "phonegap",
+    version: "1.0",
+    name: "PhoneGap",
+    type: "platform",
+
+    persistencePrefix: "phonegap-",
+
+    config: require('ripple/platform/phonegap/1.0/spec/config'),
+    device: require('ripple/platform/phonegap/1.0/spec/device'),
+    ui: require('ripple/platform/phonegap/1.0/spec/ui'),
+    events: require('ripple/platform/phonegap/1.0/spec/events'),
+
+    objects: {
+        PhoneGap: {
+            path: "phonegap/1.0/PhoneGap"
+        },
+        Coordinates: {
+            path: "w3c/1.0/Coordinates"
+        },
+        Position: {
+            path: "w3c/1.0/Position"
+        },
+        PositionError: {
+            path: "w3c/1.0/PositionError"
+        },
+        Acceleration: {
+            path: "phonegap/1.0/Acceleration"
+        },
+        navigator: {
+            path: "phonegap/1.0/navigator",
+            children: {
+                accelerometer: {
+                    path: "phonegap/1.0/accelerometer"
+                },
+                geolocation: {
+                    path: "w3c/1.0/geolocation"
+                },
+                notification: {
+                    path: "phonegap/1.0/notification"
+                },
+                contacts: {
+                    path: "phonegap/1.0/contacts"
+                },
+                network: {
+                    path: "phonegap/1.0/network"
+                },
+                camera: {
+                    path: "phonegap/1.0/camera"
+                },
+                sms: {
+                    path: "phonegap/1.0/sms"
+                },
+                telephony: {
+                    path: "phonegap/1.0/telephony"
+                },
+                map: {
+                    path: "phonegap/1.0/map"
+                },
+                orientation: {
+                    path: "phonegap/1.0/orientation"
+                },
+                system: {
+                    path: "phonegap/1.0/system"
+                },
+                compass: {
+                    path: "phonegap/1.0/compass"
+                }
+            }
+        },
+        ContactError: {
+            path: "phonegap/1.0/ContactError"
+        },
+        Contact: {
+            path: "phonegap/1.0/Contact"
+        },
+        ContactName: {
+            path: "phonegap/1.0/ContactName"
+        },
+        ContactAccount: {
+            path: "phonegap/1.0/ContactAccount"
+        },
+        ContactAddress: {
+            path: "phonegap/1.0/ContactAddress"
+        },
+        ContactOrganization: {
+            path: "phonegap/1.0/ContactOrganization"
+        },
+        ContactFindOptions: {
+            path: "phonegap/1.0/ContactFindOptions"
+        },
+        ContactField: {
+            path: "phonegap/1.0/ContactField"
+        },
+        NetworkStatus: {
+            path: "phonegap/1.0/NetworkStatus"
+        },
+        device: {
+            path: "phonegap/1.0/device"
+        },
+        SystemInfoOptions: {
+            path: "phonegap/1.0/SystemInfoOptions"
+        },
+        PowerAttributes: {
+            path: "phonegap/1.0/PowerAttributes"
+        },
+        CPUAttributes: {
+            path: "phonegap/1.0/CPUAttributes"
+        },
+        ThermalAttributes: {
+            path: "phonegap/1.0/ThermalAttributes"
+        },
+        NetworkAttributes: {
+            path: "phonegap/1.0/NetworkAttributes"
+        },
+        Connection: {
+            path: "phonegap/1.0/Connection"
+        },
+        ConnectionAttributes: {
+            path: "phonegap/1.0/ConnectionAttributes"
+        },
+        SensorAttributes: {
+            path: "phonegap/1.0/SensorAttributes"
+        },
+        AVCodecsAttributes: {
+            path: "phonegap/1.0/AVCodecsAttributes"
+        },
+        AudioCodecAttributes: {
+            path: "phonegap/1.0/AudioCodecAttributes"
+        },
+        VideoCodecAttributes: {
+            path: "phonegap/1.0/VideoCodecAttributes"
+        },
+        StorageUnitAttributes: {
+            path: "phonegap/1.0/StorageUnitAttributes"
+        },
+        InputDevicesAttributes: {
+            path: "phonegap/1.0/InputDevicesAttributes"
+        },
+        OutputDevicesAttributes: {
+            path: "phonegap/1.0/OutputDevicesAttributes"
+        },
+        DisplayDeviceAttributes: {
+            path: "phonegap/1.0/DisplayDeviceAttributes"
+        },
+        AudioDeviceAttributes: {
+            path: "phonegap/1.0/AudioDeviceAttributes"
+        },
+        PrintingDeviceAttributes: {
+            path: "phonegap/1.0/PrintingDeviceAttributes"
+        },
+        BrailleDeviceAttributes: {
+            path: "phonegap/1.0/BrailleDeviceAttributes"
+        },
+        PointerAttributes: {
+            path: "phonegap/1.0/PointerAttributes"
+        },
+        KeyboardAttributes: {
+            path: "phonegap/1.0/KeyboardAttributes"
+        },
+        CameraAttributes: {
+            path: "phonegap/1.0/CameraAttributes"
+        },
+        MicrophoneAttributes: {
+            path: "phonegap/1.0/MicrophoneAttributes"
+        }
+    }
+
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/notification', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var notifications = require('ripple/notifications'),
+    constants = require('ripple/constants'),
+    _console = require('ripple/console'),
+    ui = require('ripple/ui'),
+    goodVibrations = require('ripple/ui/plugins/goodVibrations');
+
+module.exports = {
+    alert: function (message, title, buttonName) {
+        notifications.openNotification("normal", message);
+    },
+
+    beep: function (times) {
+        for (var i = times; i > 0; i--) {
+            _console.log("beep!");
+        }
+        notifications.openNotification("normal", "BEEP x " + times);
+    },
+
+    vibrate: function (milliseconds) {
+        milliseconds = milliseconds || 500;
+        goodVibrations.vibrateDevice(milliseconds);
+    }
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/SensorAttributes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (value, min, max, normalizedValue) {
+    return {
+        value: value,
+        min: min,
+        max: max,
+        normalizedValue: normalizedValue
+    };
+};
+
+});
+require.define('ripple/platform/phonegap/1.0/network', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var deviceSettings = require('ripple/deviceSettings'),
+    utils = require('ripple/utils'),
+    NetworkStatus = require('ripple/platform/phonegap/1.0/NetworkStatus'),
+    _self = {
+        connection: {
+        }
+    };
+
+_self.connection.__defineGetter__("type", function () {
+    return deviceSettings.retrieve("NetworkStatus.connectionType");
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/w3c/1.0/PositionError', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self = function () {
+    return {
+        code: undefined,
+        message: undefined
+    };
+};
+
+_self.PERMISSION_DENIED = "PERMISSION_DENIED";
+_self.POSITION_UNAVAILABLE = "POSITION_UNAVAILABLE";
+_self.TIMEOUT = "TIMEOUT";
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/w3c/1.0/SensorConnection', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    platform = require('ripple/platform'),
+    event = require('ripple/event'),
+    sensorSettings = require('ripple/sensorSettings'),
+    accelerometer = require('ripple/accelerometer'),
+    exception = require('ripple/exception'),
+
+    _permission = true,
+    _self;
+
+function ErrorMsg() {
+    this.__defineGetter__("UNKNOWN_ERROR", function () {
+        return "An unknown error has occurred.";
+    });
+
+    this.__defineGetter__("TYPE_MISMATCH_ERROR", function () {
+        return "The object type is incompatible with the expected type.";
+    });
+
+    this.__defineGetter__("INVALID_VALUES_ERROR", function () {
+        return "The content of an object does not contain valid values.";
+    });
+
+    this.__defineGetter__("ILLEGAL_STATE", function () {
+        return "The status of connection is illegal.";
+    });
+}
+
+// TODO: Should be replaced by a global object in tizen 1.0
+function ErrorCode() {
+    this.__defineGetter__("UNKNOWN_ERR", function () {
+        return 0;
+    });
+
+    this.__defineGetter__("INVALID_VALUES_ERROR", function () {
+        return 1;
+    });
+
+    this.__defineGetter__("TYPE_MISMATCH_ERROR", function () {
+        return 2;
+    });
+
+    this.__defineGetter__("ILLEGAL_STATE", function () {
+        return 3;
+    });
+}
+
+function SensorError(code, msg) {
+    this.__defineGetter__("message", function () {
+        return msg;
+    });
+    this.__defineGetter__("code", function () {
+        return code;
+    });
+
+    this.PERMISSION_DENIED = -100;
+}
+
+function Event() {
+    var _self = {
+        CAPTURING_PHASE: 1,
+        AT_TARGET:  2,
+        BUBBLING_PHASE: 3,
+
+        type: '',
+        target: null, //new EventTarget(),
+        currentTarget: null, //new EventTarget(),
+        eventPhase: 0,
+        bubbles: false,
+        cancelable: false,
+        timeStamp: 0
+    };
+        
+    this.__defineGetter__("type", function () {
+        return _self.type;
+    });
+
+    this.__defineGetter__("target", function () {
+        return _self.target;
+    });
+
+    this.__defineGetter__("currentTarget", function () {
+        return _self.currentTarget;
+    });
+
+    this.__defineGetter__("eventPhase", function () {
+        return _self.eventPhase;
+    });    
+
+    this.__defineGetter__("bubbles", function () {
+        return _self.bubbles;
+    });
+
+    this.__defineGetter__("cancelable", function () {
+        return _self.cancelable;
+    });
+    
+    this.__defineGetter__("timeStamp", function () {
+        return _self.timeStamp;
+    });
+
+    this.stopPropagation = function () {};
+
+    this.preventDefault = function () {};
+
+    this.initEvent = function (eventTypeArg, canBubbleArg, cancelableArg) {
+        _self.type = eventTypeArg;
+        _self.bubbles = canBubbleArg;
+        _self.cancelable = cancelableArg;
+    };
+
+    return _self;
+}
+
+function SensorDataEvent() {
+    var _self = {
+        data: 0,
+        accuracy: 0,
+        timestamp: 0,
+        reason: ''
+    };
+
+    // This type of event inherit from Event
+    Event.call(this);
+
+    this.__defineGetter__("data", function () {
+        return _self.data;
+    });
+
+    this.__defineGetter__("accuracy", function () {
+        return _self.accuracy;
+    });
+
+    this.__defineGetter__("timestamp", function () {
+        return _self.timestamp;
+    });
+
+    this.__defineGetter__("reason", function () {
+        return _self.reason;
+    });
+
+    this.initSensorDataEvent = function (type, bubbles, cancelable, reason, timestamp, accuracy, data) {
+        this.initEvent(type, bubbles, cancelable);
+
+        _self.reason = reason;
+        _self.timestamp = timestamp;
+        _self.accuracy = accuracy;
+        
+        // If the data has only one part, just return the value, not the data object    
+        if (utils.count(data) === 1) {
+            utils.forEach(data, function (section, key) {
+                _self.data = data[key];
+            });
+        }
+        else {
+            _self.data = utils.copy(data);
+        }
+    };
+}
+
+// As only one sensor will be used during the simulation with a SensorConnection object,
+// we can get that sensor object first and then the following read or write operations will be simplified
+function _getSensorObj(type, name) {
+    var settings = platform.current().sensor, _sensor;
+
+    utils.forEach(settings, function (settingSection, settingType) {
+        if (settingSection.type === type) {
+
+            if (settingSection.name && settingSection.name !== name) {
+                return;
+            }
+
+            _sensor = utils.copy(settingSection);
+        }
+    });
+
+    return _sensor;
+}
+
+function _getAccelerometerData(dataType) {
+    var accelerometerData, data = {};
+
+    switch (dataType) {
+    case "Accelerometer":
+        accelerometerData = accelerometer.getInfo();
+        data = {
+            x: accelerometerData.acceleration.x,
+            y: accelerometerData.acceleration.y,
+            z: accelerometerData.acceleration.z
+        };
+        break;
+    case "Rotation":
+        accelerometerData = accelerometer.getInfo();
+        data = {
+            x: accelerometerData.orientation.alpha,
+            y: accelerometerData.orientation.beta,
+            z: accelerometerData.orientation.gamma
+        };
+        break;
+    case "Orientation":
+        accelerometerData = accelerometer.getInfo();
+        data = {
+            alpha: accelerometerData.orientation.alpha,
+            beta: accelerometerData.orientation.beta,
+            gamma: accelerometerData.orientation.gamma
+        };
+        break;
+    default:
+        break;
+    }
+
+    return data;
+}
+
+// The parameter of event callback is an object that contains the latest value, not the value itself,
+// so we need a function to create such object.
+function _getSensorData(sensorType, sensor, onerror) {
+    var data = {}, value;
+
+    if (sensorType === "Accelerometer" || sensorType === "Rotation" || sensorType === "Orientation") {
+        return _getAccelerometerData(sensorType);
+    }
+
+    utils.forEach(sensor, function (sensorSection, key) {
+        try {
+            value = sensorSettings.retrieve(sensorType + "." + key);
+        }
+        catch (e) {
+            if (onerror) {
+                onerror(e);
+            }
+        }
+        
+        if (value) {
+            data[key] = value;
+        }                    
+    });
+    
+    return data;
+}
+
+// As the event type in sensor.js file are named in this way, so we can get it with this function.
+function _getSensorEventTypes(type, sensor) {
+    var types = [];
+
+    if (type === "Accelerometer" || type === "Rotation" || type === "Orientation") {
+        return ["AccelerometerInfoChangedEvent"];
+    }
+
+    utils.forEach(sensor, function (sensorSection, sensorType) {
+        if (typeof sensorSection === "object") {
+            types.push(type + "-" + sensorType + "Changed");
+        }
+    });
+
+    return types;
+}
+
+function _onEventCallback(type, options, currentSensor, length, eventCallback, onerror) {
+    return function (values) {
+        var sensorEvent = new SensorDataEvent();
+
+        // Only the sensor that has one attribute could be compared with the threshold
+        if (options && options.threshold && length === 1 && values[0] < options.threshold) {
+            return;
+        }
+
+        if (eventCallback) {
+            sensorEvent.initSensorDataEvent(type, false, false, "read", (new Date()).getTime(), 
+                                            currentSensor.resolution, _getSensorData(type, currentSensor, onerror));
+
+            eventCallback(sensorEvent);
+        }
+    };
+}
+
+function _bind(name, obj) {
+    var callback = null;
+
+    obj.__defineGetter__(name, function () {
+        return callback;
+    });
+
+    obj.__defineSetter__(name, function (cb) {
+        callback = cb;
+    });
+
+    return {
+        get: function () {
+            return callback;
+        },
+        set: function (value) {
+            callback = value;
+        },
+        exec: function (arg) {
+            return callback && callback(arg);
+        },
+        unbind: function (cb) {
+            callback = cb === callback ? null : callback;
+        }
+    };
+}
+
+function SensorConnection(type, name) {
+    var _self,
+        currentSensor = _getSensorObj(type, name),
+        sensorEvent = new SensorDataEvent(),
+        sensorEventTypes = _getSensorEventTypes(type, currentSensor),
+        watches = [],
+        _errorCode = new ErrorCode(),
+        _errorMsg = new ErrorMsg(),
+        sensorListener;
+
+    if (currentSensor) {
+        _self = {
+            sensor: {
+                resolution: currentSensor.resolution,
+                minDelay: currentSensor.minDelay,
+                range: currentSensor.range,
+                name: currentSensor.name,
+                type: currentSensor.type
+            },
+            status: "open",
+            error: null,
+            read: function () {
+
+                if (_self.status !== "open" && _self.status !== "watching") {
+                    exception.raise(exception.types.Argument, "illegal state", new SensorError(_errorCode.ILLEGAL_STATE, _errorMsg.ILLEGAL_STATE));
+                    return;
+                }                
+
+                setTimeout(function () {
+                    if (sensorListener.get()) {
+                        sensorEvent.initSensorDataEvent(type, false, false, "read", (new Date()).getTime(), 
+                                                        currentSensor.resolution, _getSensorData(type, currentSensor, _self.onerror));
+
+                        sensorListener.exec(sensorEvent);
+                    }
+                }, 1);  
+
+                return;
+            },
+
+            startWatch: function (options) {
+                var index, watchId, watchObj = {};
+
+                if (_self.status !== "open") {
+                    exception.raise(exception.types.Argument, "illegal state", new SensorError(_errorCode.ILLEGAL_STATE, _errorMsg.ILLEGAL_STATE));
+                    return;
+                }
+                    
+                if (typeof options !== "object") {
+                    if (_self.onerror) {
+                        _self.onerror(new SensorError(_errorCode.TYPE_MISMATCH_ERROR, _errorMsg.TYPE_MISMATCH_ERROR));
+                    }
+                }
+
+                setTimeout(function () {
+                    watchId = (new Date()).getTime();   
+
+                    // As there will be many attributes for some sensor, each of them is needed to be watched.
+                    for (index = 0; index < sensorEventTypes.length; index++) {
+                        watchObj = {
+                            eventType: sensorEventTypes[index],
+                            onEvent: _onEventCallback(type, options, currentSensor, sensorEventTypes.length, sensorListener.get(), _self.onerror),
+                        };
+
+                        watches.push(watchObj);
+                        if (watchObj.eventType) {
+                            event.on(watchObj.eventType, watchObj.onEvent);                                               
+                        }
+                    }
+
+                    
+                    if (options && options.interval) {
+                        watchObj.intervalId = setInterval(_onEventCallback(type, options, currentSensor, sensorEventTypes.length, sensorListener.get(), _self.onerror), 
+                                                          options.interval);
+                    }
+
+                    _self.status = "watching";
+                    if (_self.onstatuschange) {
+                        _self.onstatuschange();
+                    }
+                                                                                                        
+                }, 1);  
+
+                return;
+            },
+
+            endWatch: function () {
+                var index, watchObj;
+
+                if (_self.status !== "watching") {
+                    exception.raise(exception.types.Argument, "illegal state", new SensorError(_errorCode.ILLEGAL_STATE, _errorMsg.ILLEGAL_STATE));
+                    return;
+                }
+
+                for (index = 0; index < watches.length; index++) {
+                    watchObj = watches[index];
+
+                    try {
+                        event.deleteEventHandler(watchObj.eventType, watchObj.onEvent);  
+                    }
+                    catch (e) {
+                        if (_self.onerror) {
+                            _self.onerror(e);
+                        }
+                    }
+
+                    if (watchObj.intervalId) {
+                        clearInterval(watchObj.intervalId);
+                    }                
+                }
+
+                watches = [];
+
+                _self.status = "open";
+                if (_self.onstatuschange) {
+                    _self.onstatuschange();
+                }
+            },
+
+            // These functions are inherited from the EventTarget object
+            addEventListener: function (eventType, callback, useCapture) {
+                var sensorEvent;
+                
+                if (eventType === "sensordata") {
+                    sensorListener.set(callback);  
+
+                    event.on("sensordata", function (data) {
+                        sensorEvent = new SensorDataEvent();        
+                        sensorEvent.initSensorDataEvent("sensordata", false, false, "read", (new Date()).getTime(), 
+                                                        currentSensor.resolution, _getSensorData(type, currentSensor, _self.onerror));           
+
+                        sensorListener.exec(sensorEvent);
+                    });             
+                }               
+            },
+
+            removeEventListener: function (eventType, callback) {
+                event.clear(eventType, callback);
+                sensorListener.unbind(callback);                                
+            },
+
+            dispatchEvent: function (evt) {
+                event.trigger("sensordata", evt);
+            }
+        };
+
+        sensorListener = _bind("onsensordata", _self);
+    }    
+
+    return _self;
+}
+
+module.exports = function (option) {
+    var connectionObj,
+        _errorCode = new ErrorCode(),
+        _errorMsg = new ErrorMsg();
+
+    if (option === null || option === undefined) {
+        return null;
+    }
+
+    // There are two ways to construct an object
+    if (typeof option === "object") {
+        if ((option.type === null || option.type === undefined) &&
+            (option.name === null || option.name === undefined)) {
+            // Spec: If none of the dictionary members are defined then raise an instantiation exception    
+            exception.raise(exception.types.Argument, "type illegal", new SensorError(_errorCode.ILLEGAL_TYPE, _errorMsg.ILLEGAL_TYPE));             
+        }
+
+        connectionObj = new SensorConnection(option.type, option.name);
+    }
+    else if (typeof option === "string") {
+        connectionObj = new SensorConnection(option, option);
+    }
+
+    return connectionObj;
+};
+
+});
+require.define('ripple/platform/w3c/1.0/Rotation', function (require, module, exports) {
+module.exports = function (alpha, beta, gamma) {
+    return {
+        alpha: alpha || 0,    //Rotation about the 'z' axis expressed in degrees [0, 360].    (Number)
+        beta: beta || 0,      //Rotation about the 'x' axis expressed in degrees [-180, 180]. (Number)
+        gamma: gamma || 0     //Rotation about the 'y' axis expressed in degrees [-90, 90].   (Number)
+    };
+};
+
+});
+require.define('ripple/platform/w3c/1.0/geolocation', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var platform = require('ripple/platform'),
+    utils = require('ripple/utils'),
+    geo = require('ripple/geo'),
+    event = require('ripple/event'),
+    Position = require('ripple/platform/w3c/1.0/Position'),
+    PositionError = require('ripple/platform/w3c/1.0/PositionError'),
+    _watches = {},
+    _self;
+
+function createPosition() {
+    var position = new Position(),
+        positionInfo = geo.getPositionInfo();
+
+    position.coords.latitude = positionInfo.latitude;
+    position.coords.longitude = positionInfo.longitude;
+    position.coords.altitude = positionInfo.altitude;
+    position.coords.altitudeAccuracy = positionInfo.altitudeAccuracy;
+    position.coords.accuracy = positionInfo.accuracy;
+    position.coords.heading = positionInfo.heading;
+    position.coords.speed = positionInfo.speed;
+    position.timestamp = positionInfo.timeStamp.getTime();
+
+    return position;
+}
+
+_self = {
+    getCurrentPosition: function (onSuccess, onError) {
+        var delay = ((geo.delay || 0) * 1000) || 1,
+            timeout = geo.timeout;
+
+        window.setTimeout(function () {
+            if (timeout) {
+                var error = new PositionError();
+                error.code = PositionError.TIMEOUT;
+                error.message = "postion timed out";
+
+                onError(error);
+            }
+            else {
+                // TODO: build facility to trigger onError() from emulator
+                // see pivotal item: https://www.pivotaltracker.com/story/show/7040343
+                _self.lastPosition = createPosition();
+                onSuccess(_self.lastPosition);
+            }
+        }, delay);
+    },
+
+    watchPosition: function (geolocationSuccess, geolocationError, geolocationOptions) {
+        var watchId = (new Date()).getTime().toString(),
+            watchObj = {};
+
+        if (geolocationOptions &&
+                geolocationOptions.frequency && typeof
+                geolocationOptions.frequency === "number" &&
+                geolocationOptions.frequency === Math.floor(geolocationOptions.frequency)) {
+
+            watchObj = {
+                onSuccess: geolocationSuccess,
+                onError: geolocationError,
+                interval: geolocationOptions.frequency
+            };
+
+            _watches[watchId] = watchObj;
+
+            _watches[watchId].intervalId = window.setInterval(function () {
+                _self.getCurrentPosition(_watches[watchId].onSuccess, _watches[watchId].onError);
+            }, geolocationOptions.frequency);
+
+        }
+        else {
+            if (typeof geolocationError === "function") {
+                window.setTimeout(function () {
+                    geolocationError();
+                }, 1);
+            }
+        }
+
+        return watchId;
+    },
+
+    lastPosition: null,
+
+    clearWatch: function (watchId) {
+        window.clearInterval(_watches[watchId].intervalId);
+        delete _watches[watchId];
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/w3c/1.0/navigator', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _original = window.navigator,
+    utils = require('ripple/utils'),
+    devices = require('ripple/devices'),
+    constants = require('ripple/constants'),
+    _self = {};
+
+(function () {
+    var key,
+        nav = window.navigator;
+
+    function _handle(obj, key) {
+        return typeof obj[key] !== "function" ? obj[key] : function () {
+            return obj[key].apply(obj, Array.prototype.slice.call(arguments));
+        };
+    }
+
+    for (key in nav) {
+        _self[key] = _handle(nav, key);
+    }
+}());
+
+_self.__defineGetter__('userAgent', function () {
+    var currentUserAgent = devices.getCurrentDevice().userAgent;
+
+    return currentUserAgent === constants.COMMON.USER_AGENT_DEFAULT ?
+        _original.userAgent : currentUserAgent;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/w3c/1.0/Acceleration', function (require, module, exports) {
+module.exports = function (x, y, z) {
+    return {
+        x: x || 0,    //Acceleration in the 'x' expressed in m/s^2. (Number)
+        y: y || 0,    //Acceleration in the 'y' expressed in m/s^2. (Number)
+        z: z || 0     //Acceleration in the 'z' expressed in m/s^2. (Number)
+    };
+};
+
+});
+require.define('ripple/platform/w3c/1.0/Position', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var Coordinates = require('ripple/platform/w3c/1.0/Coordinates');
+
+module.exports = function () {
+    return {
+        coords: new Coordinates(),
+        timestamp: new Date().getTime()
+    };
+};
+
+});
+require.define('ripple/platform/w3c/1.0/Coordinates', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function (latitude, longitude, altitude, accuracy, altitudeAccuracy, heading, speed) {
+    return {
+        latitude: latitude || 0,                    //Latitude in decimal degrees. (Number)
+        longitude: longitude || 0,                  //Longitude in decimal degrees. (Number)
+        altitude: altitude || 0,                    //Height of the position in meters above the ellipsoid. (Number)
+        accuracy: accuracy || 0,                    //Accuracy level of the latitude and longitude coordinates in meters. (Number)
+        altitudeAccuracy: altitudeAccuracy || 0,    //Accuracy level of the altitude coordinate in meters. (Number)
+        heading: heading || 0,                      //Direction of travel, specified in degrees counting clockwise relative to the true north. (Number)
+        speed: speed || 0                           //Current ground speed of the device, specified in meters per second. (Number)
+    };
+};
+
+});
+require.define('ripple/platform/tizen/1.0/TZDate', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    tz = require('ripple/platform/tizen/1.0/timezone_info'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    _Month = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+    _Day = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
+
+module.exports = function (dt) {
+    var d, UTCd, UTC_diff, tzid = "", target_diff, temp_date,
+    time = require('ripple/platform/tizen/1.0/time'),
+        hour = arguments[3] || 0, min = arguments[4] || 0,
+        sec = arguments[5] || 0, msec = arguments[6] || 0,
+
+    _d2UTCd_sync = function () {
+        UTCd = new Date(d.valueOf() - (UTC_diff * 1000 * 60 * 60));
+    },
+    _UTCd2d_sync = function () {
+        d = new Date(UTCd.valueOf() + (UTC_diff * 1000 * 60 * 60));
+    },
+    _getValue = function (o) {
+        var other;
+        other = new Date(o.getUTCFullYear(), o.getUTCMonth(), o.getUTCDate(),
+                    o.getUTCHours(), o.getUTCMinutes(), o.getUTCSeconds(), o.getUTCMilliseconds());
+        return other.valueOf();
+    },
+    _int_range_check = function (v, _min, _max) {
+        tizen1_utils.validateArgumentType(v, "integer",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        if (v > _max || v < _min) {
+            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+        }
+    };
+
+    if (arguments[7] !== undefined) {
+        tzid = arguments[7];
+    }
+
+    if (dt === null || dt === undefined) {
+        temp_date = new Date();
+        target_diff = tz.getTimezoneDiff(time.getLocalTimezone());
+        d = new Date(temp_date.valueOf() + (target_diff + temp_date.getTimezoneOffset() / 60) * 1000 * 60 * 60);
+    } else {
+        if (tizen1_utils.isValidDate(dt)) {
+            d = new Date(dt);
+            if (arguments[1] !== undefined) {
+                tzid = arguments[1];
+            }
+        } else {
+            _int_range_check(arguments[0], 1000, 9999);
+            _int_range_check(arguments[1], 0, 11);
+            _int_range_check(arguments[2], 1, 31);
+            d = new Date(arguments[0], arguments[1], arguments[2], hour, min, sec, msec);
+        }
+    }
+
+    if (tz.isValidTimezone(tzid) === false) {
+        tzid = time.getLocalTimezone();
+    }
+    UTC_diff = tz.getTimezoneDiff(tzid);
+    _d2UTCd_sync();
+
+    return {
+        getDate: function () {
+            return d.getDate();
+        },
+        setDate: function (dt) {
+            _int_range_check(dt, 1, 31);
+            d.setDate(dt);
+            _d2UTCd_sync();
+        },
+        getDay: function () {
+            return d.getDay();
+        },
+        getFullYear: function () {
+            return d.getFullYear();
+        },
+        setFullYear: function (yr) {
+            _int_range_check(yr, 1000, 9999);
+            d.setFullYear(yr);
+            _d2UTCd_sync();
+        },
+        getHours: function () {
+            return d.getHours();
+        },
+        setHours: function (hr) {
+            _int_range_check(hr, 0, 23);
+            d.setHours(hr);
+            _d2UTCd_sync();
+        },
+        getMilliseconds: function () {
+            return d.getMilliseconds();
+        },
+        setMilliseconds: function (msec) {
+            _int_range_check(msec, 0, 999);
+            d.setMilliseconds();
+            _d2UTCd_sync();
+        },
+        getMinutes: function () {
+            return d.getMinutes();
+        },
+        setMinutes: function (min) {
+            _int_range_check(min, 0, 59);
+            UTCd.setMinutes(min);
+            d.setMinutes(min);
+            _d2UTCd_sync();
+        },
+        getMonth: function () {
+            return d.getMonth();
+        },
+        setMonth: function (m) {
+            _int_range_check(m, 0, 11);
+            d.setMonth(m);
+            _d2UTCd_sync();
+        },
+        getSeconds: function () {
+            return d.getSeconds();
+        },
+        setSeconds: function (s) {
+            _int_range_check(s, 0, 59);
+            d.setSeconds(s);
+            _d2UTCd_sync();
+        },
+        getUTCDate: function () {
+            return UTCd.getDate();
+        },
+        setUTCDate: function (dt) {
+            _int_range_check(dt, 1, 31);
+            UTCd.setDate(dt);
+            _UTCd2d_sync();
+        },
+        getUTCDay: function () {
+            return UTCd.getDay();
+        },
+        getUTCFullYear: function () {
+            return UTCd.getFullYear();
+        },
+        setUTCFullYear: function (yr) {
+            _int_range_check(yr, 1000, 9999);
+            UTCd.setFullYear(yr);
+            _UTCd2d_sync();
+        },
+        getUTCHours: function () {
+            return UTCd.getHours();
+        },
+        setUTCHours: function (hr) {
+            _int_range_check(hr, 0, 23);
+            UTCd.setHours(hr);
+            _UTCd2d_sync();
+        },
+        getUTCMilliseconds: function () {
+            return UTCd.getMilliseconds();
+        },
+        setUTCMilliseconds: function (msec) {
+            _int_range_check(msec, 0, 999);
+            UTCd.setMilliseconds(msec);
+            _UTCd2d_sync();
+        },
+        getUTCMinutes: function () {
+            return UTCd.getMinutes();
+        },
+        setUTCMinutes: function (min) {
+            _int_range_check(min, 0, 59);
+            UTCd.setMinutes(min);
+            _UTCd2d_sync();
+        },
+        getUTCMonth: function () {
+            return UTCd.getMonth();
+        },
+        setUTCMonth: function (m) {
+            _int_range_check(m, 0, 11);
+            UTCd.setMonth(m);
+            _UTCd2d_sync();
+        },
+        getUTCSeconds: function () {
+            return UTCd.getSeconds();
+        },
+        setUTCSeconds: function (s) {
+            _int_range_check(s, 0, 59);
+            UTCd.setSeconds(s);
+            _UTCd2d_sync();
+        },
+        getTimezone: function () {
+            return tzid;
+        },
+        toTimezone: function (new_tzid) {
+            var diff,
+                Tzdate = require('ripple/platform/tizen/1.0/TZDate');
+            if (typeof new_tzid !== 'string') {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            if (tz.isValidTimezone(new_tzid) === true) {
+                diff = tz.getTimezoneDiff(new_tzid) - UTC_diff;
+                return new Tzdate(new Date(d.valueOf() + (diff * 1000 * 60 * 60)), new_tzid);
+            } else {
+                throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+            }
+        },
+        toLocalTimezone: function () {
+            var diff,
+                Tzdate = require('ripple/platform/tizen/1.0/TZDate'),
+                localTzid = time.getLocalTimezone();
+
+            diff = tz.getTimezoneDiff(localTzid) - UTC_diff;
+            return new Tzdate(new Date(d.valueOf() + (diff * 1000 * 60 * 60)), localTzid);
+        },
+        toUTC: function () {
+            var Tzdate = require('ripple/platform/tizen/1.0/TZDate');
+            return new Tzdate(UTCd, "UTC");
+        },
+        difference: function (other) {
+            var diff,
+                TDur = require('ripple/platform/tizen/1.0/TimeDuration');
+            if (typeof other !== 'object') {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            diff = (UTCd.valueOf() - _getValue(other));
+            return new TDur(diff).difference(new TDur(0));
+        },
+        equalsTo: function (other) {
+            if (typeof other !== 'object') {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            return (UTCd.valueOf() === _getValue(other));
+        },
+        earlierThan: function (other) {
+            if (typeof other !== 'object') {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            return (UTCd.valueOf() < _getValue(other));
+        },
+        laterThan: function (other) {
+            if (typeof other !== 'object') {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            return (UTCd.valueOf() > _getValue(other));
+        },
+        addDuration: function (dur) {
+            var Tzdate = require('ripple/platform/tizen/1.0/TZDate'),
+                Tunit = {"MSECS": 1,
+                         "SECS": 1000,
+                         "MINS": 60 * 1000,
+                         "HOURS": 60 * 60 * 1000,
+                         "DAYS": 24 * 60 * 60 * 1000
+                        };
+            if (dur.length === undefined || dur.length === null ||
+                dur.unit === undefined || dur.unit === null) {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            if ((typeof dur.length) !== 'number') {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            if (Tunit[dur.unit] === undefined) {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            return new Tzdate(new Date(d.valueOf() + (dur.length * Tunit[dur.unit])), tzid);
+        },
+        toLocaleDateString: function () {
+            return this.toDateString() + " (" + tz.getTimezoneAbbr(tzid) + ")";
+        },
+        toLocaleTimeString: function () {
+            return this.toTimeString() + " (" + tz.getTimezoneAbbr(tzid) + ")";
+        },
+        toLocaleString: function () {
+            return this.toString() + " (" + tz.getTimezoneAbbr(tzid) + ")";
+        },
+        toDateString: function () {
+            var i, ret = "", fmt = time.getDateFormat();
+            for (i = 0; i < fmt.length; i++) {
+                switch (fmt.charAt(i)) {
+                case 'd':
+                    ret = ret + d.getDate();
+                    break;
+                case 'y':
+                    ret = ret + d.getFullYear();
+                    break;
+                case 'm':
+                    ret = ret + (d.getMonth() + 1);
+                    break;
+                case 'M':
+                    ret = ret + _Month[d.getMonth()];
+                    break;
+                case 'D':
+                    ret = ret + _Day[d.getDay()];
+                    break;
+                default:
+                    ret = ret + fmt.charAt(i);
+                }
+            }
+            return ret;
+        },
+        toTimeString: function () {
+            var i, hh, mm, ss, AP,
+                ret = "", fmt = time.getTimeFormat();
+
+            if (fmt.search(/ap/) === -1) {
+                AP = false;
+            } else {
+                AP = true;
+                if (d.getHours() > 11) {
+                    fmt = fmt.replace("ap", "PM");
+                } else {
+                    fmt = fmt.replace("ap", "AM");
+                }
+            }
+            for (i = 0; i < fmt.length; i++) {
+                switch (fmt.charAt(i)) {
+                case 'h':
+                    hh = d.getHours();
+                    if (AP) {
+                        hh = (hh > 12) ? hh - 12 : hh;
+                    }
+                    hh = (hh < 10 ? "0" : "") + hh;
+                    ret = ret + hh;
+                    break;
+                case 'm':
+                    mm = d.getMinutes();
+                    mm = (mm < 10 ? "0" : "") + mm;
+                    ret = ret + mm;
+                    break;
+                case 's':
+                    ss = d.getSeconds();
+                    ss = (ss < 10 ? "0" : "") + ss;
+                    ret = ret + ss;
+                    break;
+                default:
+                    ret = ret + fmt.charAt(i);
+                }
+            }
+            return ret;
+        },
+        toString: function () {
+            return (this.toDateString() + " " + this.toTimeString());
+        },
+        getTimezoneAbbreviation: function () {
+            return tz.getTimezoneAbbr(tzid);
+        },
+        secondsFromUTC: function () {
+            return (-1 * UTC_diff * 60 * 60);
+        },
+        isDST: function () {
+            throw (new WebAPIError(errorcode.NOT_SUPPORTED_ERR));
+        },
+        getPreviousDSTTransition: function () {
+            throw (new WebAPIError(errorcode.NOT_SUPPORTED_ERR));
+        },
+        getNextDSTTransition: function () {
+            throw (new WebAPIError(errorcode.NOT_SUPPORTED_ERR));
+        }
+    };
+};
+
+});
+require.define('ripple/platform/tizen/1.0/SimpleCoordinates', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+module.exports = function (_latitude, _longitude) {
+    return {
+        latitude: _latitude || 0,
+        longitude: _longitude || 0
+    };
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/battery', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    _data = {
+        charging: true,
+        chargingTime: 0,
+        level: 1.0,
+        dischargingTime: Infinity,
+        chargingchange: {},
+        chargingtimechange: {},
+        levelchange: {},
+        dischargingtimechange: {}
+    },
+    _self;
+
+_self = {
+    addEventListener: function (event, callback, capture) {
+        if (typeof callback !== "function" || event === undefined) {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        switch (event) {
+        case "chargingchange":
+        case "chargingtimechange":
+        case "levelchange":
+        case "dischargingtimechange":
+            var isExist = false, item;
+            for (item in _data[event]) {
+                if (callback === item) {
+                    isExist = true;
+                    break;
+                }
+            }
+            if (!isExist) {
+                _data[event].add(callback);
+            }
+            break;
+
+        default:
+            break;
+        }
+    },
+
+    removeEventListener: function (event, callback, capture) {
+        if (typeof callback !== "function" || event === undefined) {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        _data[event].unbind(callback);
+    },
+
+    dispatchEvent: function (event) {
+        if (event === undefined) {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        return _data[event].exec(event);
+    }
+};
+
+_self.__defineGetter__("charging", function () {
+    return _data.charging;
+});
+
+_self.__defineGetter__("chargingTime", function () {
+    return _data.chargingTime;
+});
+
+_self.__defineGetter__("level", function () {
+    return _data.level;
+});
+
+_self.__defineGetter__("dischargingTime", function () {
+    return _data.dischargingTime;
+});
+
+function _initialize() {
+    var callback = [];
+
+    function bind(name) {
+        _self.__defineGetter__(name, function () {
+            return callback;
+        });
+
+        _self.__defineSetter__(name, function (cb) {
+            callback = cb;
+        });
+
+        return {
+            get: function () {
+                return callback;
+            },
+
+            set: function (value) {
+                callback = value;
+            },
+
+            add: function (value) {
+                callback.push(value);
+            },
+
+            exec: function (arg) {
+                callback.forEach(function (callback) {
+                    return !callback || callback(arg);
+                });
+            },
+
+            unbind: function (value) {
+                if (value === undefined) {
+                    callback = [];
+                } else {
+                    utils.forEach(callback, function (callback, index) {
+                        if (callback === value) {
+                            callback.splice(index, 1);
+                        }
+                    });
+                }
+            }
+        };
+    }
+
+    _data.chargingchange        = bind("onchargingchange");
+    _data.chargingtimechange    = bind("onchargingtimechange");
+    _data.levelchange           = bind("onlevelchange");
+    _data.dischargingtimechange = bind("ondischargingtimechange");
+
+    event.on("BatteryEvent", function (status) {
+        for (var ev in status) {
+            if ((status[ev] !== undefined) && (status[ev] !== _data[ev])) {
+                _data[ev] = status[ev];
+            }
+        }
+        _data[status.type].exec();
+    });
+}
+
+_initialize();
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/MessagingService', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var event = require('ripple/event'),
+    Message = require('ripple/platform/tizen/1.0/Message'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    PrivMessage = require('ripple/platform/tizen/1.0/PrivMessage'),
+    MessageStorage = require('ripple/platform/tizen/1.0/MessageStorage'),
+    utils = require('ripple/utils'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    msg_utils = require('ripple/platform/tizen/1.0/msg_utils'),
+    _self,
+    TIZEN_DEFAULT_MSG_FROM = {"messaging.sms": "13572468",
+                              "messaging.mms": "13572468",
+                              "messaging.email": "tizen.simulator@tizen.org"},
+    INCOMING_TYPE = {"messaging.sms": "sms",
+                     "messaging.mms": "mms",
+                     "messaging.email": "email"};
+
+_self = function (id, name, type, security_check) {
+    var msg_service = {},
+        pendingOperations = {},
+        _msgSending = {},
+        _receivedEmails = [],
+        _id = id,
+        _name = name,
+        _type = type,
+        _security_check = security_check,
+        _from = TIZEN_DEFAULT_MSG_FROM[_type],
+        _incomingType = INCOMING_TYPE[_type],
+        _messages = msg_utils.loadMsg(_type, _id),
+        _messageStorage = new MessageStorage(_messages, _security_check);
+
+    event.on("MessageSent", function (rst) {
+        var i, rsp_ok = [], rsp_fail = [];
+        // rst.msg is the real msg in module
+        if (rst.msg.priv.type !== _type ||
+            rst.msg.priv.serviceId !== _id) {
+            // not my msg
+            return;
+        }
+        if (_msgSending[rst.id] !== undefined) {
+            for (i in rst) {
+                if ((i !== "id") && (i !== "msg")) {
+                    if (rst[i] === true) {
+                        rsp_ok.push(i);
+                    } else {
+                        rsp_fail.push(i);
+                    }
+                }
+            }
+            rst.msg.priv.folderId = "SENTBOX";
+            if (rsp_fail.length === 0) {
+                rst.msg.priv.messageStatus = "SENT";
+                _msgSending[rst.id].onsuccess(rsp_ok);
+            } else {
+                rst.msg.priv.messageStatus = "FAILED";
+                _msgSending[rst.id].onerror(rsp_fail);
+            }
+            msg_utils.saveMsg(rst.msg);  // sync to remote
+            event.trigger("MsgSentRst", [rst.msg]);
+            delete _msgSending[rst.id];
+        }
+    });
+
+    event.on("MessageReceived", function (rst) {
+        var m, opt = {}, msgInit = {}, msg = {};
+
+        if (rst.type !== _incomingType) {
+            // not my msg
+            return;
+        }
+        msgInit.plainBody = rst.body;
+        msgInit.to = [_from];
+        // TODO: handle attachment
+        if (msg_utils.setMsg(msgInit, msg) === false) {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR, "received message error"));
+        }
+        opt.id = Math.uuid(8, 16);
+        opt.serviceId = _id;
+        opt.conversationId = opt.id;
+        opt.folderId = "INBOX";
+        opt.type = _type;
+        opt.timestamp = new Date();
+        opt.from = rst.from;
+        if (msg.attachments.length === 0) {
+            opt.hasAttachment = false;
+        } else {
+            opt.hasAttachment = true;
+        }
+        opt.messageStatus = "RECEIVED";
+        m = new PrivMessage(msg, opt);
+        msg_utils.saveMsg(m);   // save in server
+        if (_type !== "messaging.email") {
+            _messages.msg[m.priv.id] = m;  // sync to local
+            event.trigger("MsgRecv", [m]);
+        } else {
+            _receivedEmails.push(m);  // don't sync to local yet
+        }
+    });
+
+    msg_service = {
+        sendMessage: function (_msg, onSuccess, onError) {
+            var m, msg = {}, opt = {}, shortMsg = {}, rst = {}, _sendMsg;
+            if (_security_check.send === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            if (_msg === null || _msg === undefined || _msg.id === undefined) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+
+            if (msg_utils.setMsg(_msg, msg) === false) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+            _sendMsg = function () {
+                if (typeof _msg.id === 'string') {
+                    if (_messages.msg[_msg.id] === undefined) {
+                        if (onError) {
+                            setTimeout(function () {
+                                onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
+                            }, 1);
+                        }
+                        return;
+                    }
+                    if (_messages.msg[_msg.id].priv.messageStatus === "DRAFT") {
+                        msg_utils.delMsg(_messages.msg[_msg.id]);
+                        delete _messages.msg[_msg.id];
+                    } else {
+                        // if msg found in storage, it can only be a draft.
+                        if (onError) {
+                            setTimeout(function () {
+                                onError(new WebAPIError(errorcode.SECURITY_ERR));
+                            }, 1);
+                        }
+                        return;
+                    }
+                }
+                opt.id = Math.uuid(8, 16);
+                opt.serviceId = _id;
+                if ((msg.inResponseTo !== null) &&
+                    (_messages.msg[msg.inResponseTo] !== undefined) &&
+                    (_messages.msg[msg.inResponseTo].priv.messageStatus !== "DRAFT")) {
+                    opt.conversationId = _messages.msg[msg.inResponseTo].priv.conversationId;
+                } else {
+                    opt.conversationId = opt.id;
+                }
+                opt.folderId = "OUTBOX";
+                opt.type = _type;
+                opt.timestamp = new Date();
+                opt.from = _from;
+                if (msg.attachments.length === 0) {
+                    opt.hasAttachment = false;
+                } else {
+                    opt.hasAttachment = true;
+                }
+                opt.messageStatus = "SENDING";
+
+                m = new PrivMessage(msg, opt);
+                _messages.msg[m.priv.id] = m;
+                msg_utils.saveMsg(m);  // sync to remote
+                shortMsg.msg = m;   // pass by ref
+                shortMsg.id = m.priv.id;
+                shortMsg.body = m.body.plainBody;
+                shortMsg.to = m.to.slice(0);
+                shortMsg.cc = m.cc.slice(0);
+                shortMsg.bcc = m.bcc.slice(0);
+                event.trigger("OutsideMessageReceived", [shortMsg]);
+                rst.onsuccess = onSuccess;
+                rst.onerror = onError;
+                _msgSending[m.priv.id] = rst;
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "messagingService:sendMsg", _sendMsg);
+        },
+
+        loadMessageBody: function (msg, onSuccess, onError) {
+            var pendingID, _loadMsgBody;
+            if (_security_check.write === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            _loadMsgBody = function () {
+                pendingID = setTimeout(function () {
+                    if (pendingOperations[pendingID] === undefined) {
+                        // has been cancelled/expired
+                        return;
+                    }
+                    delete pendingOperations[pendingID];
+                    onSuccess();
+                }, 1);
+                pendingOperations[pendingID] = onError;
+                return pendingID;
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "messagingService:loadMessageBody", _loadMsgBody);
+        },
+        loadMessageAttachment: function (msg, onSuccess, onError) {
+            var pendingID, _loadMsgAttachment;
+
+            if (_security_check.write === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            if (_messages.msg[msg.id] === undefined) {
+                throw (new WebAPIError(errorcode.NOT_FOUND_ERR));
+            }
+            _loadMsgAttachment = function () {
+                pendingID = setTimeout(function () {
+                    if (pendingOperations[pendingID] === undefined) {
+                        // has been cancelled/expired
+                        return;
+                    }
+                    delete pendingOperations[pendingID];
+                    onSuccess();
+                }, 1);
+                pendingOperations[pendingID] = onError;
+                return pendingID;
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "messagingService:loadMessageAttachment", _loadMsgAttachment);
+        },
+        sync: function (onSuccess, onError, limit) {
+            var i, m, pendingID, _sync, _onError;
+
+            if (_security_check.write === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            _onError = onError || null;
+            _sync = function () {
+                pendingID = setTimeout(function () {
+                    if (pendingOperations[pendingID] === undefined) {
+                        // has been cancelled/expired
+                        return;
+                    }
+                    delete pendingOperations[pendingID];
+                    for (i = 0; i < _receivedEmails.length; i++) {
+                        m = _receivedEmails[i];
+                        _messages.msg[m.priv.id] = m;  // sync to local
+                        event.trigger("MsgRecv", [m]);
+                    }
+                    _receivedEmails = [];
+                    onSuccess();
+                }, 1);
+                pendingOperations[pendingID] = _onError;
+                return pendingID;
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "messagingService:sync", _sync);
+        },
+
+        syncFolder: function (folder, onSuccess, onError, limit) {
+            var i, m, pendingID, _syncFolder;
+
+            if (_security_check.write === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            _syncFolder = function () {
+                pendingID = setTimeout(function () {
+                    if (pendingOperations[pendingID] === undefined) {
+                        // has been cancelled/expired
+                        return;
+                    }
+                    delete pendingOperations[pendingID];
+                    if (folder.id === "INBOX") {
+                        for (i = 0; i < _receivedEmails.length; i++) {
+                            m = _receivedEmails[i];
+                            _messages.msg[m.priv.id] = m;  // sync to local
+                            event.trigger("MsgRecv", [m]);
+                        }
+                        _receivedEmails = [];
+                    }
+                    onSuccess();
+                }, 1);
+                pendingOperations[pendingID] = onError;
+                return pendingID;
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "messagingService:syncFolder", _syncFolder);
+        },
+
+        stopSync: function (pendingID) {
+            if (_security_check.write === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            if (typeof pendingID !== number) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+            if (pendingOperations[pendingID] === undefined) {
+                return;
+            } else {
+                clearTimeout(pendingID);
+                pendingOperations[pendingID](new WebAPIError(errorcode.ABORT_ERR));
+                delete pendingOperations[pendingID];
+            }
+        }
+    };
+    msg_service.__defineGetter__("id", function () {
+        return _id;
+    });
+    msg_service.__defineGetter__("type", function () {
+        return _type;
+    });
+    msg_service.__defineGetter__("name", function () {
+        return _name;
+    });
+    msg_service.__defineGetter__("messageStorage", function () {
+        return _messageStorage;
+    });
+    return msg_service;
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/TimeDuration', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError');
+
+module.exports = function (l, u) {
+    var _length, _unit,
+        TimeDurationUnit = {"MSECS": 1,
+                            "SECS": 1000,
+                            "MINS": 60 * 1000,
+                            "HOURS": 60 * 60 * 1000,
+                            "DAYS": 24 * 60 * 60 * 1000
+                           },
+        _simplifyDuration = function (ms) {
+            var TDur = require('ripple/platform/tizen/1.0/TimeDuration'),
+                uni = "MSECS";
+            if ((ms % 1000) === 0) {
+                ms = ms / 1000;
+                uni = "SECS";
+                if ((ms % 60) === 0) {
+                    ms = ms / 60;
+                    uni = "MINS";
+                    if ((ms % 60) === 0) {
+                        ms = ms / 60;
+                        uni = "HOURS";
+                        if ((ms % 24) === 0) {
+                            ms = ms / 60;
+                            uni = "HOURS";
+                        }
+                    }
+                }
+            }
+            return (new TDur(ms, uni));
+        },
+        _toMSECS = function (unit) {
+            if (TimeDurationUnit[unit] === undefined) {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            } else {
+                return TimeDurationUnit[unit];
+            }
+        };
+
+    _length = l || 0;
+    if ((u !== undefined) && (u !== null)) {
+        if (TimeDurationUnit[u] === undefined) {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        } else {
+            _unit = u;
+        }
+    } else {
+        _unit = "MSECS";
+    }
+    return {
+        length: _length,
+        unit: _unit,
+        difference: function (o) {
+            var thisMS = _length * _toMSECS(_unit),
+                otherMS = o.length * _toMSECS(o.unit);
+            return _simplifyDuration(thisMS - otherMS);
+        },
+        equalsTo: function (o) {
+            var thisMS = _length * _toMSECS(_unit),
+                otherMS = o.length * _toMSECS(o.unit);
+            return (thisMS === otherMS);
+        },
+        lessThan: function (o) {
+            var thisMS = _length * _toMSECS(_unit),
+                otherMS = o.length * _toMSECS(o.unit);
+            return (thisMS < otherMS);
+        },
+        greaterThan: function (o) {
+            var thisMS = _length * _toMSECS(_unit),
+                otherMS = o.length * _toMSECS(o.unit);
+            return (thisMS > otherMS);
+        }
+    };
+};
+
+});
+require.define('ripple/platform/tizen/1.0/ContactAddress', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+var tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils');
+
+module.exports = function (prop) {
+    var _self, type, i;
+    _self = {};
+    if (prop) {
+        if (prop.country !== null && prop.country !== undefined) {
+            _self.country = String(prop.country);
+        }
+        if (prop.region !== null && prop.region !== undefined) {
+            _self.region = String(prop.region);
+        }
+        if (prop.city !== null && prop.city !== undefined) {
+            _self.city = String(prop.city);
+        }
+        if (prop.streetAddress !== null && prop.streetAddress !== undefined) {
+            _self.streetAddress = String(prop.streetAddress);
+        }
+        if (prop.additionalInformation !== null && prop.additionalInformation !== undefined) {
+            _self.additionalInformation = String(prop.additionalInformation);
+        }
+        if (prop.postalCode !== null && prop.postalCode !== undefined) {
+            _self.postalCode = String(prop.postalCode);
+        }
+        _self.types = [];
+        if (tizen1_utils.isValidArray(prop.types)) {
+            for (i = 0; i < prop.types.length; i++) {
+                type = String(prop.types[i]).toUpperCase();
+                _self.types.push(type);
+            }
+        }
+    }
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/alarm', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    exception = require('ripple/exception'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    Alarm = require('ripple/platform/tizen/1.0/AlarmBase'),
+    AlarmRelative = require('ripple/platform/tizen/1.0/AlarmRelative'),
+    AlarmAbsolute = require('ripple/platform/tizen/1.0/AlarmAbsolute'),
+    AlarmStore,
+    _DB_ALARMS_KEY = "tizen1.0-db-alarms",
+    PERIOD_MINUTE = 60,
+    PERIOD_HOUR   = 60 * PERIOD_MINUTE,
+    PERIOD_DAY    = 24 * PERIOD_HOUR,
+    PERIOD_WEEK   = 7 * PERIOD_DAY,
+    _alarms = {}, _alarmStack = [],
+    _security = {
+        "http://tizen.org/api/alarm": [],
+        "http://tizen.org/api/alarm.read": ["get", "getAll"],
+        "http://tizen.org/api/alarm.write": ["add", "remove", "removeAll", "getRemainingSeconds", "getNextScheduledDate"],
+        all: true
+    },
+    _isInitialized = false, _self;
+
+function _initialize() {
+    _alarms = db.retrieveObject(_DB_ALARMS_KEY);
+    utils.forEach(_alarms, function (alarmStore) {
+        _alarmStack.push(alarmStore);
+    });
+    _isInitialized = true;
+}
+
+function _get() {
+    if (!_isInitialized) {
+        _initialize();
+    }
+}
+
+function _save() {
+    db.saveObject(_DB_ALARMS_KEY, _alarmStack);
+}
+
+function _updateDB(alarmStore) {
+    _alarmStack.push(alarmStore);
+    _save();
+}
+
+function _getCurrentAppId() {
+    return db.retrieve("current-url");
+}
+
+function _checkTriggerAlarm(alarm) {
+    var remainingTime, nextTriggerDate;
+
+    if (alarm.delay !== undefined) { // Alarm is relative
+        if (alarm.period !== null)
+            return false;
+
+        remainingTime = alarm.getRemainingSeconds();
+        if (remainingTime === null)
+            return true; // This alarm is triggered, remove it
+    } else if (alarm.period !== undefined) { // Alarm is absolute,no repeat
+        nextTriggerDate = alarm.getNextScheduledDate();
+        if (nextTriggerDate === null)
+            return true; // Already triggered
+    }
+
+    return false; // Alarm is repeat, not expired
+}
+
+function _convertToAlarm(alarmStore) {
+    var alarm, frequency;
+
+    if (alarmStore.delay !== null) { // AlarmRelative
+        alarm = new AlarmRelative(alarmStore.delay, alarmStore.period);
+        alarm.date = alarmStore.date;
+    } else { // AlarmAbsolute
+        if (alarmStore.period !== null && alarmStore.period !== PERIOD_WEEK) {
+            frequency = alarmStore.period;
+        } else if (alarmStore.period === PERIOD_WEEK) {
+            frequency = alarmStore.daysOfTheWeek;
+        }
+        alarm = new AlarmAbsolute(alarmStore.date, frequency);
+    }
+    alarm.id = alarmStore.id;
+
+    return alarm;
+}
+
+function _eventCheckAlarm(id) {
+    var alarm, diff;
+
+    _get();
+    utils.forEach(_alarmStack, function (alarmStore) {
+        if (alarmStore.id !== id)
+            return;
+
+        alarm = _convertToAlarm(alarmStore);
+        if (alarm.delay !== undefined) {
+            diff = alarm.getRemainingSeconds();
+            if (0 < diff && diff < 2) {
+                event.trigger("SendTriggerAppId", [alarmStore.applicationId]);
+            }
+        } else {
+            diff = (new Date()) - alarm.getNextScheduledDate();
+            if (-2000 < diff && diff < 2000) {
+                event.trigger("SendTriggerAppId", [alarmStore.applicationId]);
+            }
+        }
+    });
+}
+
+_self = function () {
+    var currentAppId, alarm;
+
+    alarm = {
+        add: function (alarm, applicationId, argument) {
+            var alarmStore;
+
+            if (!_security.all && !_security.add)
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            if ((alarm === undefined || !(alarm instanceof Alarm) ||
+                (typeof applicationId !== "string") ||
+                (argument !== undefined && typeof argument !== "string")))
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            currentAppId = _getCurrentAppId(); // Update The Current URL.
+            alarmStore = new AlarmStore(alarm, applicationId, currentAppId, argument);
+            _updateDB(alarmStore);
+        },
+
+        remove: function (alarmId) {
+            var isFound = false, i;
+
+            if (!_security.all && !_security.remove)
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+
+            if (typeof alarmId !== "string")
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+
+            for (i in _alarmStack) {
+                if (_alarmStack[i].id !== alarmId)
+                    continue;
+
+                _alarmStack.splice(i, 1);
+                _save();
+                isFound = true;
+            }
+            if (!isFound)
+                throw (new WebAPIError(errorcode.NOT_FOUND_ERR));
+        },
+
+        removeAll: function () {
+            var availableStack = [], i;
+
+            if (!_security.all && !_security.remove)
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+
+            for (i in _alarmStack) {
+                if (_alarmStack[i].currentAppId === currentAppId)
+                    continue;
+
+                availableStack.push(_alarmStack[i]);
+            }
+            _alarmStack = availableStack;
+            _save();
+        },
+
+        getAll: function () {
+            var availableStack = [], backAlarms = [], isExpired, alarm, i;
+
+            if (!_security.all && !_security.getAll)
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+
+            for (i in _alarmStack) {
+                alarm = _convertToAlarm(_alarmStack[i]); // alarmStore --> alarm
+                isExpired = _checkTriggerAlarm(alarm); // Check if the alarm is expired
+                if (isExpired)
+                    continue;
+
+                availableStack.push(_alarmStack[i]);
+                if (_alarmStack[i].currentAppId === currentAppId)
+                    backAlarms.push(alarm);
+            }
+            _alarmStack = availableStack;
+            _save();
+            return backAlarms;
+        },
+
+        get: function (alarmId) {
+            var isFound = false, item, isExpired, alarm;
+
+            if (!_security.all && !_security.get)
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+
+            if (typeof alarmId !== "string")
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+
+            for (item in _alarmStack) {
+                if (_alarmStack[item].id === alarmId) {
+                    alarm = _convertToAlarm(_alarmStack[item]);
+                    isExpired = _checkTriggerAlarm(alarm);
+                    if (isExpired) {
+                        _alarmStack.splice(item, 1);
+                        _save();
+                    } else {
+                        isFound = true;
+                    }
+                    break;
+                }
+            }
+            if (!isFound)
+                throw (new WebAPIError(errorcode.NOT_FOUND_ERR));
+
+            return alarm;
+        },
+
+        handleSubFeatures: function (subFeatures) {
+            for (var subFeature in subFeatures) {
+                if (_security[subFeature].length === 0) {
+                    _security.all = true;
+                    return;
+                }
+                _security.all = false;
+                utils.forEach(_security[subFeature], function (method) {
+                    _security[method] = true;
+                });
+            }
+        }
+    };
+
+    currentAppId = _getCurrentAppId();
+    _get();
+
+    alarm.__defineGetter__("PERIOD_MINUTE", function () {
+        return PERIOD_MINUTE;
+    });
+
+    alarm.__defineGetter__("PERIOD_HOUR", function () {
+        return PERIOD_HOUR;
+    });
+
+    alarm.__defineGetter__("PERIOD_DAY", function () {
+        return PERIOD_DAY;
+    });
+
+    alarm.__defineGetter__("PERIOD_WEEK", function () {
+        return PERIOD_WEEK;
+    });
+
+    return alarm;
+};
+
+AlarmStore = function (alarmObject, applicationId, currentAppId, argument) {
+    var _self;
+    _self = {
+        id: alarmObject.id,
+        delay: alarmObject.delay || null,
+        date: alarmObject.date || null,
+        period: alarmObject.period || null,
+        daysOfTheWeek: alarmObject.daysOfTheWeek || null,
+        applicationId: applicationId,
+        currentAppId: currentAppId,
+        argument: argument || null
+    };
+    return _self;
+};
+
+event.on("CheckAlarm", function (id) {
+    _eventCheckAlarm(id);
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/MessageBody', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils');
+
+module.exports = function (id, isloaded, _plainbody, _htmlbody, inlineattachments) {
+    var msgbody, _id = id, _loaded = isloaded;
+    msgbody = {
+        plainBody: _plainbody,
+        htmlBody: _htmlbody,
+        inlineAttachments: [] // TODO: not support attachment yet
+    };
+    msgbody.__defineGetter__("messageId", function () {
+        return _id;
+    });
+    msgbody.__defineGetter__("loaded", function () {
+        return _loaded;
+    });
+    return msgbody;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/power', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var db = require('ripple/db'),
+    event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    constants = require('ripple/constants'),
+    deviceSettings = require('ripple/deviceSettings'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    PowerStateRequest = require('ripple/platform/tizen/1.0/PowerStateRequest'),
+    _RULES = constants.POWER_RULES,// Rule Allow: true; Deny false
+    _POWER_RESOURCE = constants.POWER_RESOURCE,
+    _CPU_STATE = constants.POWER_RESOURCE.CPU.STATE,
+    _DISPLAY_STATE = constants.POWER_RESOURCE.DISPLAY.STATE,
+    cpuState = {"previous" : null, "current" : null},
+    displayState = {"previous" : null, "current" : null},
+    _PORWER_RULES_KEY = "tizen1-db-power-role",
+    _cpuListener = {
+        "LOW" : [],
+        "HIGH" : []
+    },
+    _displayListener = {
+        "OFF" : [],
+        "DIM" : [],
+        "NORMAL" : [],
+        "BRIGHT" : []
+    },
+    _self;
+
+/**initialize**/
+function initState() {
+    var dbRules;
+    //Init power rules.
+    dbRules = db.retrieveObject(_PORWER_RULES_KEY);
+    _RULES =  dbRules && _RULES ? dbRules : _RULES;
+    event.trigger("initPowerDB", [_RULES]);
+    //Init power state.
+    updateResourceState();
+}
+
+function updatePowerRules(state, value) {
+    _RULES[state] = value;
+    db.saveObject(_PORWER_RULES_KEY, _RULES);
+}
+
+function getResourceState(resource, value) {
+    var state;
+    value = Number(value);
+    switch (resource) {
+    case "CPU" :
+        if (value <= _CPU_STATE.LOW.MAX) {
+            state = _CPU_STATE.LOW.NAME;//LOW
+        } else {
+            state = _CPU_STATE.HIGH.NAME;
+        }
+        break;
+    case "DISPLAY" :
+        if (value ===  _DISPLAY_STATE.OFF.MAX) {
+            state = _DISPLAY_STATE.OFF.NAME;
+        } else if (value <= _DISPLAY_STATE.DIM.MAX) {
+            state = _DISPLAY_STATE.DIM.NAME;
+        } else if (value <= _DISPLAY_STATE.NORMAL.MAX) {
+            state = _DISPLAY_STATE.NORMAL.NAME;
+        } else {
+            state = _DISPLAY_STATE.BRIGHT.NAME;
+        }
+        break;
+    default:
+        break;
+    }
+    return state;
+}
+
+function updateResourceState() {
+    var load, brightness, actualState;
+    // Init CPU state
+    load = deviceSettings.retrieve("Cpu.load");
+    actualState = getResourceState("CPU", load);
+    cpuState.previous = cpuState.current;
+    cpuState.current = actualState;
+    // Init DISPLAY state
+    brightness = deviceSettings.retrieve("Display.brightness");
+    actualState = getResourceState("DISPLAY", brightness);
+    displayState.previous = displayState.current;
+    displayState.current = actualState;
+}
+
+function callListeners(listeners, resource, actualState, requestState) {
+    if (listeners.length === 0) {
+        return;
+    }
+    listeners.forEach(function (listener) {
+        setTimeout(function () {
+            listener(resource, actualState, requestState);
+        }, 1);
+    });
+}
+
+function findListenerCB(resource, value, stateObj) {
+    var i, listeners, actualState = getResourceState(resource, value);
+    listeners = (resource === "CPU" ? _cpuListener : _displayListener);
+    if (!stateObj.previous) {
+        return;
+    }
+    if (stateObj.previous !== stateObj.current) {
+        callListeners(listeners[stateObj.previous], resource, actualState, stateObj.previous);
+        callListeners(listeners[stateObj.current], resource, actualState, stateObj.current);
+    }
+}
+
+function saveListenerCB(resource, state, listener) {
+    if (listener) {
+        switch (resource) {
+        case "CPU" :
+            _cpuListener[state].push(listener);
+            break;
+        case "DISPLAY" :
+            _displayListener[state].push(listener);
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+_self = {
+    request: function (request, successCB, errorCB, listener) {
+        var resource, state, value, actualState;
+        //Check all parameters.
+        tizen1_utils.validateCallbackType(listener);
+        tizen1_utils.validateCallbackType(successCB, errorCB);
+        if (!request || !request.resource || !request.minimalState) {
+            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+        }
+        resource = request.resource;
+        state = request.minimalState;
+        //Check resource
+        if (!_POWER_RESOURCE.hasOwnProperty(resource)) {
+            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+        }
+        //Check state
+        if (!_POWER_RESOURCE[resource].STATE.hasOwnProperty(state)) {
+            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+        }
+        saveListenerCB(resource, state, listener);
+        //Check the state rule
+        if (!_RULES[state]) {//Deny
+            actualState = resource === "CPU" ? cpuState : displayState;
+            if (errorCB) {
+                setTimeout(function () {
+                    errorCB(new WebAPIError(errorcode.NOT_SUPPORTED_ERR));
+                }, 1);
+            }
+            if (listener) {
+                setTimeout(function () {
+                    listener(resource, actualState.current, state);
+                }, 1);
+            }
+            return;
+        }
+        switch (resource) {
+        case "CPU" :
+            value = _CPU_STATE[state].VALUE;// Update Cpu.load.
+            deviceSettings.persist("Cpu.load", value);
+            updateResourceState();
+            findListenerCB('CPU', value, cpuState);
+            event.trigger("CpuLoadChangedByPower", [value]);
+            break;
+        case "DISPLAY" :
+            value = _DISPLAY_STATE[state].VALUE;// Update Display.brightness.
+            deviceSettings.persist("Display.brightness", value);
+            updateResourceState();
+            findListenerCB("DISPLAY", value, displayState);
+            event.trigger("DisplayBrightnessChangedByPower", [value]);
+            break;
+        default:
+            break;
+        }
+        if (successCB) {//SuccessCallback
+            setTimeout(function () {
+                successCB();
+            }, 1);
+        }
+        
+    },
+
+    release: function (resource) {
+        switch (resource) {
+        case "CPU" :
+            _cpuListener.LOW = [];
+            _cpuListener.HIGH = [];
+            break;
+        case "DISPLAY" :
+            _displayListener.OFF = [];
+            _displayListener.DIM = [];
+            _displayListener.NORMAL = [];
+            _displayListener.BRIGHT = [];
+            break;
+        default:
+            throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
+        }
+    }
+};
+
+initState();
+event.on("CpuLoadChanged", function (value) {
+    updateResourceState();
+    findListenerCB('CPU', value, cpuState);
+});
+event.on("DisplayBrightnessChanged", function (value) {
+    updateResourceState();
+    findListenerCB("DISPLAY", value, displayState);
+});
+event.on("updatePowerRules", function (object) {
+    updatePowerRules(object.state, object.value);
+});
+module.exports = _self;
+
+
+});
+require.define('ripple/platform/tizen/1.0/CalendarRecurrenceRule', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    TZDate = require('ripple/platform/tizen/1.0/TZDate');
+
+module.exports = function (frequency, ruleInitDict) {
+    var _self = {};
+
+    _self.frequency = (frequency) ? frequency : 0;
+
+    if ((ruleInitDict !== undefined) && (ruleInitDict !== null)) {
+        _self.interval        = ruleInitDict.interval;
+        _self.untilDate       = utils.copy(ruleInitDict.untilDate);
+        _self.occurrenceCount = ruleInitDict.occurrenceCount;
+        _self.daysOfTheWeek   = utils.copy(ruleInitDict.daysOfTheWeek);
+        _self.setPositions     = utils.copy(ruleInitDict.setPositions);
+        _self.exceptions      = utils.copy(ruleInitDict.exceptions);
+    } else {
+        _self.interval        = 0;
+        _self.untilDate       = new TZDate();
+        _self.occurrenceCount = 0;
+        _self.daysOfTheWeek      = [""];
+        _self.setPositions     = [];
+        _self.exceptions      = [new TZDate()];
+    }
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/CalendarItem', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    TZDate = require('ripple/platform/tizen/1.0/TZDate'),
+    CalendarRecurrenceRule = require('ripple/platform/tizen/1.0/CalendarRecurrenceRule'),
+    SimpleCoordinates = require('ripple/platform/tizen/1.0/SimpleCoordinates'),
+    CalendarItemInit,
+    CalendarEventInit,
+    CalendarTaskInit,
+    CalendarItem;
+
+CalendarItem = function (type, id, lastModificationDate) {
+    var _self;
+
+    function _2digital(number) {
+        return ((number >= 10) ? '' : '0') + number;
+    }
+
+    if ((type !== "EVENT") && (type !== "TASK"))
+        throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+    _self = (type === "EVENT") ? new CalendarEventInit() : new CalendarTaskInit();
+
+    id = id || Math.uuid(null, 16);
+    lastModificationDate = (lastModificationDate) ? utils.copy(lastModificationDate) : (new TZDate());
+
+    _self.__defineGetter__("id", function () {
+        return id;
+    });
+
+    _self.__defineGetter__("lastModificationDate", function () {
+        return lastModificationDate;
+    });
+
+    _self.clone = function () {
+        var item = new CalendarItem(type);
+
+        item.id                   = Math.uuid(null, 16);
+        item.lastModificationDate = new TZDate();
+        item.description          = _self.description;
+        item.summary              = _self.summary;
+        item.isAllDay             = _self.isAllDay;
+        item.startDate            = _self.startDate;
+        item.duration             = _self.duration;
+        item.location             = _self.location;
+        item.geolocation          = _self.geolocation;
+        item.organizer            = _self.organizer;
+        item.visibility           = _self.visibility;
+        item.status               = _self.status;
+        item.priority             = _self.priority;
+        item.alarms               = _self.alarms;
+        item.categories           = _self.categories;
+        item.attendees            = _self.attendees;
+
+        if (type === "EVENT") {
+            item.endDate          = _self.endDate;
+            item.availability     = _self.availability;
+            item.recurrenceRule   = _self.recurrenceRule;
+        } else {
+            item.dueDate          = _self.dueDate;
+            item.completedDate    = _self.completedDate;
+            item.progress         = _self.progress;
+        }
+
+        return item;
+    };
+
+    _self.convertToString = function (format) {
+        var str = "", pri, i, date, before, y, m, d, hh, mm, ss, dateStart = "", dateEnd = "",
+            header = "BEGIN:VCALENDAR\r\nPRODID:-//Tizen.org//Tizen Calendar//EN\r\nVERSION:2.0\r\n",
+            end = "END:VCALENDAR\r\n";
+
+        if (format !== "ICALENDAR_20" && format !== "VCALENDAR_10") {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERROR);
+        }
+
+        //TODO: vcalendar 1.0 doesn't support yet
+        if (format === "VCALENDAR_10") {
+            return;
+        }
+
+        str = header;
+        if (type === "EVENT") {
+            str += "BEGIN:VEVENT\r\n";
+        } else if (type === "TASK") {
+            str += "BEGIN:VTODO\r\n";
+        }
+
+        if (this.isAllDay) {
+            if (this.startDate) {
+                date = this.startDate;
+                y = date.getFullYear();
+                m = _2digital(date.getMonth() + 1);
+                d = _2digital(date.getDate());
+                str += "DTSTART;VALUE=DATE:" + y + m + d + "\r\n";
+                dateStart = "" + y + m + d + "T000000Z";
+                if (this.duration) {
+                    date = date.addDuration(this.duration);
+                    y = date.getFullYear();
+                    m = _2digital(date.getMonth() + 1);
+                    d = _2digital(date.getDate());
+                    str += "DTEND;VALUE=DATE:" + y + m + d + "\r\n";
+                    dateEnd = "" + y + m + d + "T000000Z";
+                }
+            }
+        } else {
+            if (this.startDate) {
+                date = this.startDate;
+                y = date.getFullYear();
+                m = _2digital(date.getMonth() + 1);
+                d = _2digital(date.getDate());
+                hh = _2digital(date.getHours());
+                mm = _2digital(date.getMinutes());
+                ss = _2digital(date.getSeconds());
+                str += "DTSTART:" + y + m + d + "T" + hh + mm + ss + "Z" + "\r\n";
+                dateStart = "" + y + m + d + "T" + hh + mm + ss + "Z";
+                if (this.duration && this.duration.length && this.duration.unit) {
+                    date = date.addDuration(this.duration);
+                    y = date.getFullYear();
+                    m = _2digital(date.getMonth() + 1);
+                    d = _2digital(date.getDate());
+                    hh = _2digital(date.getHours());
+                    mm = _2digital(date.getMinutes());
+                    ss = _2digital(date.getSeconds());
+                    str += "DTEND:" + y + m + d + "T" + hh + mm + ss + "Z" + "\r\n";
+                    dateEnd = "" + y + m + d + "T" + hh + mm + ss + "Z";
+                }
+            }
+        }
+
+        if (this.description) {
+            str += "DESCRIPTION:" + this.description + "\r\n";
+        }
+        if (this.summary) {
+            str += "SUMMARY:" + this.summary + "\r\n";
+        }
+        if (this.location) {
+            str += "LOCATION:" + this.location + "\r\n";
+        }
+        if (this.geolocation) {
+            // Don't need to check latitude and longitude due to they are mandatory attributes
+            str += "GEO:" + this.geolocation.latitude + "," + this.geolocation.longitude + "\r\n";
+        }
+        if (this.organizer) {
+            str += "ORGANIZER:" + this.organizer + "\r\n";
+        }
+        if (this.visibility) {
+            str += "CLASS:" + this.visibility + "\r\n";
+        }
+        if (this.status) {
+            str += "STATUS:" + this.status + "\r\n";
+        }
+        if (this.priority) {
+            switch (this.priority) {
+            case "HIGH":
+                pri = 2;
+                break;
+            case "MEDIUM":
+                pri = 5;
+                break;
+            case "LOW":
+                pri = 7;
+                break;
+            }
+            str += "PRIORITY:" + pri + "\r\n";
+        }
+        if (tizen1_utils.isValidArray(this.alarms)) {
+            for (i = 0; i < this.alarms.length; i++) {
+                str += "BEGIN:VALARM\r\n";
+                // Don't need to check this.alarms[i].method due to it is a mandatory attribute
+                str += "ACTION:" + this.alarms[i].method + "\r\n";
+                if (this.alarms[i].description) {
+                    str += "DESCRIPTION:" + this.alarms[i].description + "\r\n";
+                } else {
+                    // description property MUST included if action is DISPLAY (RFC5545 3.6.6)
+                    str += "DESCRIPTION:This is a reminder\r\n";
+                }
+                if (this.alarms[i].absoluteDate) {
+                    date = this.alarms[i].absoluteDate;
+                    y = date.getFullYear();
+                    m = _2digital(date.getMonth() + 1);
+                    d = _2digital(date.getDate());
+                    hh = _2digital(date.getHours());
+                    mm = _2digital(date.getMinutes());
+                    ss = _2digital(date.getSeconds());
+                    str += "TRIGGER;VALUE=DATE-TIME:" + y + m + d + "T" + hh + mm + ss + "Z" + "\r\n";
+                } else {
+                    //it must be included before attribute
+                    before = this.alarms[i].before;
+                    switch (before.unit) {
+                    case "DAYS":
+                        str += "TRIGGER:-P" + before.length + "D" + "\r\n";
+                        break;
+                    case "HOURS":
+                        str += "TRIGGER:-P0DT" + before.length + "H0M0S" + "\r\n";
+                        break;
+                    case "MINS":
+                        str += "TRIGGER:-P0DT0H" + before.length + "M0S" + "\r\n";
+                        break;
+                    case "SECS":
+                        str += "TRIGGER:-P0DT0H0M" + before.length + "S" + "\r\n";
+                        break;
+                    }
+                }
+                str += "END:VALARM\r\n";
+            }
+        }
+        if (tizen1_utils.isValidArray(this.categories)) {
+            str += "CATEGORIES:";
+            for (i = 0; i < this.categories.length; i++) {
+                str += this.categories[i] + ",";
+            }
+            str = str.slice(0, -1);
+            str += "\r\n";
+        }
+        if (tizen1_utils.isValidArray(this.attendees)) {
+            for (i = 0; i < this.attendees.length; i++) {
+                //TODO: basic implementation
+                str += "ATTENDEE:mailto:" + this.attendees[i].uri + "\r\n";
+            }
+        }
+
+        if (type === "EVENT" && this.availability && dateStart !== "" && dateEnd !== "") {
+            switch (this.availability) {
+            case "BUSY":
+                str += "FREEBUSY;FBTYPE=BUSY:";
+                break;
+            case "FREE":
+                str += "FREEBUSY;FBTYPE=FREE:";
+                break;
+            }
+            str += dateStart + "/" + dateEnd + "\r\n";
+        }
+        //TODO: endDate doesn't support (CalendarEvent specific property)
+        //TODO: recurrenceRule doesn't support (CalendarEvent specific property)
+        //TODO: dueDate doesn't support (CalendarTask specific property)
+        //TODO: completeDate doesn't support (CalendarTask specific property)
+        if (type === "TASK" && this.progress) {
+            str += "PERCENT-COMPLETE:" + this.progress + "\r\n";
+        }
+
+        if (type === "EVENT") {
+            str += "END:VEVENT\r\n";
+        } else if (type === "TASK") {
+            str += "END:VTODO\r\n";
+        }
+        str += end;
+    };
+
+    return _self;
+};
+
+CalendarItemInit = function () {
+    return {
+        description: "",
+        summary:     "",
+        isAllDay:    false,
+        startDate:   new TZDate(),
+        duration:    {},
+        location:    "",
+        geolocation: new SimpleCoordinates(),
+        organizer:   "",
+        visibility:  "",
+        status:      "",
+        priority:    "",
+        alarms:      [],
+        categories:  [""],
+        attendees:   []
+    };
+};
+
+CalendarEventInit = function () {
+    var _self = new CalendarItemInit();
+
+    _self.endDate        = new TZDate();
+    _self.availability   = "";
+    _self.recurrenceRule = new CalendarRecurrenceRule();
+
+    return _self;
+};
+
+CalendarTaskInit = function () {
+    var _self = new CalendarItemInit();
+
+    _self.dueDate       = new TZDate();
+    _self.completedDate = new TZDate();
+    _self.progress      = 0;
+
+    return _self;
+};
+
+module.exports = CalendarItem;
+
+});
+require.define('ripple/platform/tizen/1.0/PrivMessage', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils');
+
+module.exports = function (m, opt) {
+    return {
+// readonly begin
+        priv: {id: opt.id,
+               serviceId: opt.serviceId,
+               conversationId: opt.conversationId,
+               folderId: opt.folderId,
+               type: opt.type,
+               timestamp: new Date(opt.timestamp),
+               from: opt.from,
+               hasAttachment: opt.hasAttachment,
+               messageStatus: opt.messageStatus
+        },
+// readonly end
+        to: m.to.slice(0),
+        cc: m.cc.slice(0),
+        bcc: m.bcc.slice(0),
+        body: utils.copy(m.body),
+        isRead: m.isRead,
+        isHighPriority: m.isHighPriority,
+        subject: m.subject,
+        inResponseTo: m.inResponseTo,
+        attachments: utils.copy(m.attachments)
+    };
+};
+
+});
+require.define('ripple/platform/tizen/1.0/ContactPhoneNumber', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+var tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils');
+
+module.exports = function (number, types) {
+    var _self, _number = "", i,
+        _types = [], type;
+    
+    if (number) {
+        _number = String(number);
+    }
+    if (tizen1_utils.isValidArray(types)) {
+        for (i = 0; i < types.length; i++) {
+            type = String(types[i]).toUpperCase();
+            _types.push(type);
+        }
+    }
+
+    _self = {
+        number : _number,
+        types : _types
+    };
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/POIGeometry', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var SimpleCoordinates = require('ripple/platform/tizen/1.0/SimpleCoordinates'),
+    GeoRectBounds = require('ripple/platform/tizen/1.0/GeoRectBounds');
+
+module.exports = function (position, viewport, wkt) {
+    var _self, _position = null, _viewport = null, _wkt = "";
+
+    if (position) {
+        _position = new SimpleCoordinates(position.latitude, position.longitude);
+    }
+
+    if (viewport) {
+        _viewport = new GeoRectBounds(viewport.southWest, viewport.northEast);
+    }
+
+    if (wkt) {
+        _wkt = String(wkt);
+    }
+
+    _self = {
+        position : _position,
+        viewport: _viewport,
+        wkt: _wkt
+    };
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/CalendarEvent', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var TZDate = require('ripple/platform/tizen/1.0/TZDate'),
+    CalendarItem = require('ripple/platform/tizen/1.0/CalendarItem'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    SimpleCoordinates = require('ripple/platform/tizen/1.0/SimpleCoordinates'),
+    CalendarRecurrenceRule = require('ripple/platform/tizen/1.0/CalendarRecurrenceRule');
+
+module.exports = function (eventInitDict) {
+    var _self, isDetached = false; //isDetached
+
+    _self = new CalendarItem("EVENT");
+
+    if ((eventInitDict !== undefined) && (eventInitDict !== null)) {
+        _self.endDate        = eventInitDict.endDate;
+        _self.availability   = eventInitDict.availability;
+        _self.recurrenceRule = eventInitDict.recurrenceRule;
+        if (eventInitDict.description) {
+            _self.description = String(eventInitDict.description);
+        }
+        if (eventInitDict.summary) {
+            _self.summary = String(eventInitDict.summary);
+        }
+        if (eventInitDict.isAllDay && (typeof eventInitDict.isAllDay === "boolean")) {
+            _self.isAllDay = eventInitDict.isAllDay;
+        }
+        if (eventInitDict.startDate && tizen1_utils.isValidTZDate(eventInitDict.startDate)) {
+            _self.startDate = eventInitDict.startDate;
+        }
+        if (eventInitDict.duration && (typeof eventInitDict.duration === "object")) {
+            _self.duration = new TZDate(eventInitDict.duration);
+        }
+        if (eventInitDict.location) {
+            _self.location = String(eventInitDict.location);
+        }
+        if (eventInitDict.geolocation && eventInitDict.geolocation.latitude && eventInitDict.geolocation.longitude) {
+            _self.geolocation = new SimpleCoordinates(eventInitDict.geolocation.latitude, eventInitDict.geolocation.longitude);
+        }
+        if (eventInitDict.organizer) {
+            _self.organizer = String(eventInitDict.organizer);
+        }
+        if (eventInitDict.visibility) {
+            _self.visibility = String(eventInitDict.visibility);
+        }
+        if (eventInitDict.status) {
+            _self.status = String(eventInitDict.status);
+        }
+        if (eventInitDict.priority) {
+            _self.priority = String(eventInitDict.priority);
+        }
+        if (eventInitDict.alarms && tizen1_utils.isValidArray(eventInitDict.alarms)) {
+            var isInValid = false;
+            eventInitDict.alarms.some(function (alarm) {
+                if (!alarm || alarm.method === undefined) {// 'method' is CalendarAlarm's property.
+                    isInValid = true;
+                    return;
+                }
+            });
+            if (!isInValid) {
+                _self.alarms = eventInitDict.alarms;
+            }
+        }
+        if (eventInitDict.categories && tizen1_utils.isValidArray(eventInitDict.categories)) {
+            var isInValid = false;
+            eventInitDict.categories.some(function (categorie) {
+                if (!categorie || typeof categorie !== "string") {
+                    isInValid = true;
+                    return;
+                }
+            });
+            if (!isInValid) {
+                _self.categories = eventInitDict.categories;
+            }
+        }
+        if (eventInitDict.attendees && tizen1_utils.isValidArray(eventInitDict.attendees)) {
+            var isInValid = false;
+            eventInitDict.attendees.some(function (attendee) {
+                if (!attendee || attendee.uri === undefined) {// 'uri' is CalendarAttendee's property.
+                    isInValid = true;
+                    return;
+                }
+            });
+            if (!isInValid) {
+                _self.attendees = eventInitDict.attendees;
+            }
+        }
+    } else {
+        _self.endDate        = new TZDate();
+        _self.availability   = "";
+        _self.recurrenceRule = new CalendarRecurrenceRule();
+    }
+
+    _self.expandRecurrence = function (startDate, endDate, successCallback, errorCallback) {
+        _self.startDate = startDate;
+        _self.endDate   = endDate;
+    };
+    _self.__defineGetter__("isDetached", function () {
+        return isDetached;
+    });
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/map', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var lbs = require('ripple/platform/tizen/1.0/lbs_utils'),
+    mapProviders = [],
+    MapStyle,
+    MapProvider,
+    _self;
+
+function _initialize() {
+    // EPSG:3857 is a Spherical Mercator projection coordinate system popularized by web services such as Google and later OpenStreetMap
+    // mapStyles are from http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
+    var projection = "EPSG:3857",
+        mapStyle1 = new MapStyle("Mapnik", "http://b.tile.openstreetmap.org/${z}/${x}/${y}.png"),
+        mapStyle2 = new MapStyle("Cycle", "http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png");
+
+    mapProviders = [new MapProvider({name: "OpenStreetMap", connectivity: "ONLINE"}, projection, [mapStyle1, mapStyle2])];
+}
+
+_self = {
+    getDefaultProvider: function () {
+        return mapProviders[0];
+    },
+    getProviders: function () {
+        return mapProviders;
+    }
+};
+
+MapStyle = function (name, url) {
+    return {
+        name: name,
+        url: url
+    };
+};
+
+MapProvider = function (prop, projection, mapStyles) {
+    var mapProvider = new lbs.LocationServiceProvider(prop);
+
+    mapProvider.__defineGetter__("projection", function () {
+        return projection;
+    });
+
+    mapProvider.__defineGetter__("mapStyles", function () {
+        return mapStyles;
+    });
+
+    return mapProvider;
+};
+
+_initialize();
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/ContactAccount', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+module.exports = function (id, accountURI) {
+    var _self, _id, _uri;
+
+    if (id) {
+        _id = String(id);
+    }
+
+    if (accountURI) {
+        _uri = String(accountURI);
+    }
+
+    _self = {
+        accountServiceId : _id,
+        contactURI : _uri
+    };
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/ApplicationServiceData', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils');
+
+module.exports = function (key, value) {
+    this.key = String(key);
+    this.value = [];
+
+    if (tizen1_utils.isValidArray(value)) {
+        for (var i in value) {
+            this.value.push(String(value[i]));
+        }
+    }
+};
+
+});
+require.define('ripple/platform/tizen/1.0/CompositeFilter', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+module.exports = function (_type, _filters) {
+    return {
+        type: _type,
+        filters: _filters
+    };
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/ReverseGeocodeOptions', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    SortMode = require('ripple/platform/tizen/1.0/SortMode');
+
+module.exports = function (_sortMode, _resultType, _maxResults) {
+    var _self;
+    if (_sortMode !== null && _sortMode !== undefined) {
+        if (typeof _sortMode !== "object") {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        try {
+            new SortMode(_sortMode.attributeName, _sortMode.order);
+        } catch (e) {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+    }
+    if (_resultType !== null && _resultType !== undefined) {
+        if (_resultType !== "FORMATTED" && _resultType !== "STRUCTURED") {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+    }
+    if (_maxResults !== null && _maxResults !== undefined) {
+        if (typeof _maxResults !== "number") {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+    }
+    _self = {
+        sortMode : _sortMode,
+        resultType : _resultType || "FORMATTED",
+        maxResults : _maxResults || 0
+    };
+
+    return _self;
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/tizen1_utils', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var self,
+    utils = require('ripple/utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError');
+
+self = module.exports = {
+    _wac2_regexSanitize: function (regexString) {
+        var escapePattern = /([^\\]|^)(%)/g, percentPattern = /\\%/g;
+        return regexString.replace("^", "\\^")
+                .replace("$", "\\$")
+                .replace("(", "\\(")
+                .replace(")", "\\)")
+                .replace("<", "\\<")
+                .replace("[", "\\[")
+                .replace("{", "\\{")
+                .replace(/\\([^%])/, "\\\\$1")    /* don't replace \\% */
+                .replace("|", "\\|")
+                .replace(">", "\\>")
+                .replace(".", "\\.")
+                .replace("*", "\\*")
+                .replace("+", "\\+")
+                .replace("?", "\\?")
+                .replace(escapePattern, "$1.*")  /* replace % with .* */
+                .replace(percentPattern, "%");   /* strip excape of % */
+    },
+
+    isValidDate: function (d) {
+        if (Object.prototype.toString.call(d) !== "[object Date]")
+            return false;
+        return !isNaN(d.getTime());
+    },
+    isValidTZDate: function (d) {
+        if (Object.prototype.toString.call(d) !== "[object Object]")
+            return false;
+        return d.getTimezone && !isNaN(d.getDate());//getTimezone() belongs to TZDate
+    },
+    isValidArray: function (a) {
+        return (Object.prototype.toString.call(a) === "[object Array]");
+    },
+
+    matchOptionArrayString: function (src, attr, pattern) {
+        /* src.obj[attr] is a StringArray */
+        var _pattern, re, _stringMatch;
+        _pattern = this._wac2_regexSanitize(pattern);
+        re = new RegExp("^" + _pattern + "$", "i");
+
+        _stringMatch = function (obj, index) {
+            if (pattern.search(/^%*$/i) === 0)
+                return true;
+            if (obj[attr] === undefined || obj[attr] === null)
+                return false;
+            return obj[attr].some(function (f) {
+                return f.search(re) !== -1;
+            });
+        };
+        return utils.filter(src, _stringMatch);
+    },
+
+    matchAttributeBooleanFilter: function (src, attr, value) {
+        // only support EXACTLY matchFlag
+        var _booleanMatch, atr = attr.split(".");
+
+        if (atr.length === 2) {
+            _booleanMatch = function (obj, index) {
+                return (obj[atr[0]][atr[1]] === value);
+            };
+        } else {
+            _booleanMatch = function (obj, index) {
+                return (obj[attr] === value);
+            };
+        }
+
+        return utils.filter(src, _booleanMatch);
+    },
+
+    matchAttributeArrayFilter: function (src, attr, matchFlag, value) {
+        var _re, _arrayMatch, atr = attr.split("."), _existMatch;
+
+        if (atr.length === 2) {
+            _existMatch = function (obj, index) {
+                return (obj[atr[0]][atr[1]] !== undefined);
+            };
+        } else {
+            _existMatch = function (obj, index) {
+                return (obj[attr] !== undefined);
+            };
+        }
+
+        if (value === undefined) {
+            return utils.filter(src, _existMatch);
+        }
+
+        switch (matchFlag)
+        {
+        case "EXACTLY":
+            _re = new RegExp("^" + value + "$");
+            break;
+        case "FULLSTRING":
+            _re = new RegExp("^" + value + "$", "i");
+            break;
+        case "CONTAINS":
+            _re = new RegExp(value, "i");
+            break;
+        case "STARTSWITH":
+            _re = new RegExp("^" + value, "i");
+            break;
+        case "ENDSWITH":
+            _re = new RegExp(value + "$", "i");
+            break;
+        case "EXISTS":
+            return utils.filter(src, _existMatch);
+        default:
+            return [];
+        }
+
+        if (atr.length === 2) {
+            _arrayMatch = function (obj, index) {
+                return (obj[atr[0]][atr[1]].some(function (o) {
+                    return (o.search(_re) !== -1);
+                }));
+            };
+        } else {
+            _arrayMatch = function (obj, index) {
+                return (obj[attr].some(function (o) {
+                    return (o.search(_re) !== -1);
+                }));
+            };
+        }
+
+        return utils.filter(src, _arrayMatch);
+    },
+
+    matchAttributeRangeFilter: function (src, attr, low, high) {
+        var _rangeMatch, atr = attr.split(".");
+
+        if (atr.length === 2) {
+            _rangeMatch = function (obj, index) {
+                var matched = true;
+                if (low !== null && low !== undefined) {
+                    matched = (obj[atr[0]][atr[1]] >= low);
+                }
+                if (matched && (high !== null && high !== undefined)) {
+                    matched = (obj[atr[0]][atr[1]] <= high);
+                }
+                return matched;
+            };
+        } else {
+            _rangeMatch = function (obj, index) {
+                var matched = true;
+                if (low !== null && low !== undefined) {
+                    matched = (obj[attr] >= low);
+                }
+                if (matched && (high !== null && high !== undefined)) {
+                    matched = (obj[attr] <= high);
+                }
+                return matched;
+            };
+        }
+        return utils.filter(src, _rangeMatch);
+    },
+
+    matchAttributeFilter: function (src, attr, matchFlag, value) {
+        var _re, _stringMatch, atr = attr.split("."),
+            _existMatch;
+
+        if (atr.length === 2) {
+            _existMatch = function (obj, index) {
+                return (obj[atr[0]][atr[1]] !== undefined);
+            };
+        } else {
+            _existMatch = function (obj, index) {
+                return (obj[attr] !== undefined);
+            };
+        }
+
+        if (value === undefined) {
+            return utils.filter(src, _existMatch);
+        }
+
+        switch (matchFlag)
+        {
+        case "EXACTLY":
+            _re = new RegExp("^" + value + "$");
+            break;
+        case "FULLSTRING":
+            _re = new RegExp("^" + value + "$", "i");
+            break;
+        case "CONTAINS":
+            _re = new RegExp(value, "i");
+            break;
+        case "STARTSWITH":
+            _re = new RegExp("^" + value, "i");
+            break;
+        case "ENDSWITH":
+            _re = new RegExp(value + "$", "i");
+            break;
+        case "EXISTS":
+            return utils.filter(src, _existMatch);
+        default:
+            return [];
+        }
+        if (atr.length === 2) {
+            _stringMatch = function (obj, index) {
+                if (typeof obj[atr[0]][atr[1]] !== 'string') {
+                    return false;
+                } else {
+                    return (obj[atr[0]][atr[1]].search(_re) !== -1);
+                }
+            };
+        } else {
+            _stringMatch = function (obj, index) {
+                if (typeof obj[attr] !== 'string') {
+                    return false;
+                } else {
+                    return (obj[attr].search(_re) !== -1);
+                }
+            };
+        }
+        return utils.filter(src, _stringMatch);
+    },
+
+    matchOptionString: function (src, attr, pattern) {
+        /* src.obj[attr] is a string */
+        var _stringMatch, _pattern, _re;
+        _pattern = this._wac2_regexSanitize(pattern);
+        _re = new RegExp("^" + _pattern + "$", "mi");
+
+        _stringMatch = function (obj, index) {
+            return (obj[attr].search(_re) !== -1);
+        };
+        return utils.filter(src, _stringMatch);
+    },
+
+    matchOptionDate: function (src, attr, filterStart, filterEnd) {
+        var _dateMatch;
+        _dateMatch = function (obj, index) {
+            var matched = true, valueDate = obj[attr];
+
+            if (filterStart !== undefined && filterStart !== null) {
+                matched = (valueDate.getTime() >= filterStart.getTime());
+            }
+            if (matched && (filterEnd !== undefined && filterEnd !== null)) {
+                matched = (valueDate.getTime() <= filterEnd.getTime());
+            }
+            return matched;
+        };
+        return utils.filter(src, _dateMatch);
+    },
+
+    matchOptionShortArray: function (src, attr, filterArray) {
+        /* src.obj[attr] is a short, filterArray is an array
+           i.e. find status is [CONFRIMED or TENTATIVE] */
+        var arraySome = function (obj, index) {
+            return filterArray.some(function (f) {
+                return f === obj[attr];
+            });
+        };
+        return utils.filter(src, arraySome);
+    },
+
+    validateArgumentType: function (arg, argType, errorObj) {
+        var invalidArg = false;
+
+        switch (argType) {
+        case "array":
+            if (!arg instanceof Array) {
+                invalidArg = true;
+            }
+            break;
+        case "date":
+            if (!arg instanceof Date) {
+                invalidArg = true;
+            }
+            break;
+        case "integer":
+            if (typeof Number(arg) !== "number" || Number(arg) !== Math.floor(arg)) {
+                invalidArg = true;
+            }
+            break;
+        default:
+            if (typeof arg !== argType) {
+                invalidArg = true;
+            }
+            break;
+        }
+
+        if (invalidArg) {
+            throw errorObj;
+        }
+    },
+
+    validateCallbackType: function (successCallback, errorCallback) {
+        if (successCallback) {
+            this.validateArgumentType(successCallback, "function",
+                new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (errorCallback) {
+            this.validateArgumentType(errorCallback, "function",
+                new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+    },
+
+    validateEqualArrays: function (arrayOne, arrayTwo) {
+        var isEqual = false, i;
+
+        if (Object.prototype.toString.call(arrayTwo) === "[object Array]" &&
+            Object.prototype.toString.call(arrayTwo) === "[object Array]" &&
+            arrayOne.length === arrayTwo.length) {
+            isEqual = true;
+            for (i in arrayOne) {
+                if (arrayOne[i] !== arrayTwo[i]) {
+                    isEqual = false;
+                    break;
+                }
+            }
+        }
+        return isEqual;
+    },
+
+    validateTypeMismatch: function (onSuccess, onError, name, callback) {
+
+        if (onSuccess === undefined || onSuccess === null) {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+        if (onSuccess) {
+            this.validateArgumentType(onSuccess, "function",
+                                      new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (onError) {
+            this.validateArgumentType(onError, "function",
+                                      new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+
+        return callback && callback();
+    },
+
+    isEmptyObject: function (obj) {
+        var prop;
+
+        for (prop in obj) {
+            return false;
+        }
+        return true;
+    },
+
+    arrayComposite: function (mode, arrayA, arrayB) {
+        var combinedArray = arrayA.concat(arrayB),
+            intersectionArray = arrayA.filter(function (value) {
+                if (utils.arrayContains(arrayB, value)) {
+                    return true;
+                }
+
+                return false;
+            });
+
+        switch (mode) {
+        case "AND":
+        case "INTERSECTION":
+            return intersectionArray;
+        case "OR":
+        case "UNION":
+            return intersectionArray.concat(combinedArray.filter(function (value) {
+                if (utils.arrayContains(intersectionArray, value)) {
+                    return false;
+                }
+
+                return true;
+            }));
+        default:
+            return undefined;
+        }
+    },
+
+    isEqual: function (srcObj, aimObj) {
+        var i;
+
+        if (typeof srcObj !== typeof aimObj) {
+            return false;
+        }
+
+        if (srcObj === null || srcObj === undefined || typeof srcObj === 'number' ||
+            typeof srcObj === 'string' || typeof srcObj === 'boolean') {
+            return srcObj === aimObj;
+        }
+
+        for (i in srcObj) {
+            if (!aimObj.hasOwnProperty(i) || !self.isEqual(srcObj[i], aimObj[i])) {
+                return false;
+            }
+        }
+
+        return true;
+    },
+
+    query: function (objects, filter, sortMode, limit, offset) {
+        function isCompositeFilter(filter) {
+            return (filter.type) ? true : false;
+        }
+
+        function isAttributeFilter(filter) {
+            return (filter.matchFlag) ? true : false;
+        }
+
+        function getValue(obj, key) {
+            var keys = key.split("."),
+                value = obj[keys[0]],
+                i;
+
+            for (i = 1; i < keys.length; i++) {
+                if (value[keys[i]]) {
+                    value = value[keys[i]];
+                }
+            }
+
+            return value;
+        }
+
+        function _filter(objects, filter) {
+            var i, results, eachResult;
+
+            if (isCompositeFilter(filter)) {
+                for (i in filter.filters) {
+                    eachResult = _filter(objects, filter.filters[i]);
+                    results = (results === undefined) ? eachResult : self.arrayComposite(filter.type, results, eachResult);
+                }
+                return results;
+            }
+
+            if (isAttributeFilter(filter)) {
+                results = self.matchAttributeFilter(objects, filter.attributeName, filter.matchFlag, filter.matchValue);
+            } else {
+                results = self.matchAttributeRangeFilter(objects, filter.attributeName, filter.initialValue, filter.endValue);
+            }
+
+            return results;
+        }
+
+        function _sort(objects, sortMode) {
+            objects.sort(function (a, b) {
+                return (sortMode.order === "ASC") ?
+                    (getValue(a, sortMode.attributeName) < getValue(b, sortMode.attributeName) ? -1 : 1):
+                    (getValue(a, sortMode.attributeName) > getValue(b, sortMode.attributeName) ? -1 : 1);
+            });
+
+            return objects;
+        }
+
+        var res;
+
+        if (filter === null || filter === undefined)
+            return objects;
+
+        res = _filter(objects, filter);
+
+        if (sortMode) {
+            _sort(res, sortMode);
+
+            // If the LIMIT expression evaluates to a negative value,
+            // then there is no upper bound on the number of rows returned.
+            // @spec: If 0, there is no limit set.
+            // If the OFFSET clause evaluates to a negative value,
+            // the results are the same as if it had evaluated to zero
+            if (limit > 0) {
+                limit = limit | 0;
+                offset = offset | 0;
+
+                offset = (offset >= 0) ? offset : 0;
+                res = res.slice(offset, limit);
+            }
+        }
+
+        return res;
+    },
+
+    copyString: function (str) {
+        var newStr, charConvert = [], i;
+
+        if (typeof str !== 'string') {
+            return str;
+        }
+        for (i = 0; i < str.length; i++) {
+            charConvert[i] = str.charAt(i);
+        }
+        newStr = charConvert.join("");
+
+        return newStr;
+    },
+
+    copy: function (obj) {
+        var i,
+            newObj = jQuery.isArray(obj) ? [] : {};
+
+        if (typeof obj === 'number' ||
+            typeof obj === 'string' ||
+            typeof obj === 'boolean' ||
+            obj === null ||
+            obj === undefined) {
+            return obj;
+        }
+
+        if (obj instanceof Date) {
+            return new Date(obj);
+        }
+
+        if (obj instanceof RegExp) {
+            return new RegExp(obj);
+        }
+
+        for (i in obj) {
+            if (obj.hasOwnProperty(i)) {
+                if (obj.__lookupGetter__(i)) {
+                    newObj.__defineGetter__(i, (function (key) {
+                        return function () {
+                            return self.copy(obj[key]);
+                        };
+                    }(i)));
+                }
+                else {
+                    newObj[i] = self.copy(obj[i]);
+                }
+            }
+        }
+
+        return newObj;
+    }
+};
+
+});
+require.define('ripple/platform/tizen/1.0/GeoCircleBounds', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (_center, _radius) {
+    var center, radius;
+    center = _center || null;
+    radius = _radius || 0;
+
+    this.__defineGetter__("center", function () {
+        return center;
+    });
+
+    this.__defineGetter__("radius", function () {
+        return radius;
+    });
+};
+
+});
+require.define('ripple/platform/tizen/1.0/ContactName', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+var tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils');
+
+module.exports = function (prop) {
+    var _self, i;
+    _self = {
+        prefix : "",
+        firstName : "",
+        middleName : "",
+        lastName : "",
+        nicknames : [],
+        phoneticName : "",
+        displayName : null
+    };
+
+    if (prop) {
+        if (prop.prefix !== null && prop.prefix !== undefined) {
+            _self.prefix = String(prop.prefix);
+        }
+        if (prop.firstName !== null && prop.firstName !== undefined) {
+            _self.firstName = String(prop.firstName);
+        }
+        if (prop.middleName !== null && prop.middleName !== undefined) {
+            _self.middleName = String(prop.middleName);
+        }
+        if (prop.lastName !== null && prop.lastName !== undefined) {
+            _self.lastName = String(prop.lastName);
+        }
+        if (tizen1_utils.isValidArray(prop.nicknames)) {
+            for (i = 0; i < prop.nicknames.length; i++) {
+                _self.nicknames.push(String(prop.nicknames[i]));
+            }
+        }
+        if (prop.phoneticName !== null && prop.phoneticName !== undefined) {
+            _self.phoneticName = String(prop.phoneticName);
+        }
+        if (prop.displayName !== null && prop.displayName !== undefined) {
+            _self.displayName = String(prop.displayName);
+        }
+    }
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/GeometryFilter', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (criteria, geometry) {
+    var _self;
+
+    _self = {
+        criteria: criteria,
+        geometry: geometry
+    };
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/Message', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    msg_utils = require('ripple/platform/tizen/1.0/msg_utils'),
+    MessageBody = require('ripple/platform/tizen/1.0/MessageBody'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError');
+
+module.exports = function (type, messageInit) {
+    var _id = null, _serviceId = null, _conversationId = null,
+        _folderId = null, _type = type, _timestamp = null,
+        _from = null, _hasAttachment = false, _messageStatus = null,
+        msg = {};
+
+    if (messageInit !== undefined && messageInit !== null) {
+        if (msg_utils.setMsg(messageInit, msg) === false) {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (messageInit.priv !== undefined) {
+            /* secret constructor for PrivateMessage */
+            _id = messageInit.priv.id;
+            _serviceId = messageInit.priv.serviceId;
+            _conversationId = messageInit.priv.conversationId;
+            _folderId = messageInit.priv.folderId;
+            _type = messageInit.priv.type;
+            _timestamp = new Date(messageInit.priv.timestamp);
+            _from = messageInit.priv.from;
+            _hasAttachment = messageInit.priv.hasAttachment;
+            _messageStatus = messageInit.priv.messageStatus;
+        }
+        msg.body = new MessageBody(_id, msg.body.loaded, msg.body.plainBody, msg.body.htmlBody, []);
+    }
+
+    msg.__defineGetter__("id", function () {
+        return _id;
+    });
+    msg.__defineGetter__("serviceId", function () {
+        return _serviceId;
+    });
+    msg.__defineGetter__("conversationId", function () {
+        return _conversationId;
+    });
+    msg.__defineGetter__("folderId", function () {
+        return _folderId;
+    });
+    msg.__defineGetter__("type", function () {
+        return _type;
+    });
+    msg.__defineGetter__("timestamp", function () {
+        return _timestamp;
+    });
+    msg.__defineGetter__("from", function () {
+        return _from;
+    });
+    msg.__defineGetter__("hasAttachment", function () {
+        return _hasAttachment;
+    });
+    msg.__defineGetter__("messageStatus", function () {
+        return _messageStatus;
+    });
+    return msg;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/poi', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var OpenMapQuestProvider = require('ripple/platform/tizen/1.0/poiBackend_openmapquest'), // opne.MapQuest.xapi service
+    _providers,
+    _security = {
+        "http://tizen.org/api/poi": [],
+        "http://tizen.org/api/poi.read": ["find"],
+        "http://tizen.org/api/poi.write": ["add", "remove", "update"],
+        all: true
+    },
+    _self;
+
+function _initialize() {
+    _providers = [new OpenMapQuestProvider({name : "MapQuest", connectivity : "ONLINE", metaData : _security})];
+}
+
+_self = function () {
+    var poi;
+
+    poi = {
+        getDefaultProvider : function () {
+            return _providers[0];
+        },
+        getProviders : function () {
+            return _providers;
+        },
+        handleSubFeatures: function (subFeatures) {
+            var i, subFeature;
+            for (subFeature in subFeatures) {
+                if (_security[subFeature].length === 0) {
+                    _security.all = true;
+                    break;
+                }
+                _security.all = false;
+                for (i = 0; i < _security[subFeature].length; i++) {
+                    _security[_security[subFeature][i]] = true;
+                }
+            }
+            _initialize();
+        }
+    };
+
+    return poi;
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/errorcode', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var _self = {};
+
+_self.__defineGetter__("UNKNOWN_ERR", function () {
+    return 0;
+});
+
+_self.__defineGetter__("INDEX_SIZE_ERR", function () {
+    return 1;
+});
+
+_self.__defineGetter__("DOMSTRING_SIZE_ERR", function () {
+    return 2;
+});
+
+_self.__defineGetter__("HIERARCHY_REQUEST_ERR", function () {
+    return 3;
+});
+
+_self.__defineGetter__("WRONG_DOCUMENT_ERR", function () {
+    return 4;
+});
+
+_self.__defineGetter__("INVALID_CHARACTER_ERR", function () {
+    return 5;
+});
+
+_self.__defineGetter__("NO_DATA_ALLOWED_ERR", function () {
+    return 6;
+});
+
+_self.__defineGetter__("NO_MODIFICATION_ALLOWED_ERR", function () {
+    return 7;
+});
+
+_self.__defineGetter__("NOT_FOUND_ERR", function () {
+    return 8;
+});
+
+_self.__defineGetter__("NOT_SUPPORTED_ERR", function () {
+    return 9;
+});
+
+_self.__defineGetter__("INUSE_ATTRIBUTE_ERR", function () {
+    return 10;
+});
+
+_self.__defineGetter__("INVALID_STATE_ERR", function () {
+    return 11;
+});
+
+_self.__defineGetter__("SYNTAX_ERR", function () {
+    return 12;
+});
+
+_self.__defineGetter__("INVALID_MODIFICATION_ERR", function () {
+    return 13;
+});
+
+_self.__defineGetter__("NAMESPACE_ERR", function () {
+    return 14;
+});
+
+_self.__defineGetter__("INVALID_ACCESS_ERR", function () {
+    return 15;
+});
+
+_self.__defineGetter__("VALIDATION_ERR", function () {
+    return 16;
+});
+
+_self.__defineGetter__("TYPE_MISMATCH_ERR", function () {
+    return 17;
+});
+
+_self.__defineGetter__("SECURITY_ERR", function () {
+    return 18;
+});
+
+_self.__defineGetter__("NETWORK_ERR", function () {
+    return 19;
+});
+
+_self.__defineGetter__("ABORT_ERR", function () {
+    return 20;
+});
+
+_self.__defineGetter__("URL_MISMATCH_ERR", function () {
+    return 21;
+});
+
+_self.__defineGetter__("QUOTA_EXCEEDED_ERR", function () {
+    return 22;
+});
+
+_self.__defineGetter__("TIMEOUT_ERR", function () {
+    return 23;
+});
+
+_self.__defineGetter__("INVALID_NODE_TYPE_ERR", function () {
+    return 24;
+});
+
+_self.__defineGetter__("DATA_CLONE_ERR", function () {
+    return 25;
+});
+
+_self.__defineGetter__("INVALID_VALUES_ERR", function () {
+    return 99;
+});
+
+_self.__defineGetter__("IO_ERR", function () {
+    return 100;
+});
+
+_self.__defineGetter__("SERVICE_NOT_AVAILABLE_ERR", function () {
+    return 111;
+});
+
+module.exports = _self;
+
+
+});
+require.define('ripple/platform/tizen/1.0/nfc', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('ripple/db'),
+    event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    _NFC_TAG = "tizen1.0-nfc-tag",
+    _NFC_PEER = "tizen1.0-nfc-peer",
+    _NFC_OUTPUT_MESSAGE = "tizen1.0-nfc-output-message",
+    NFCAdapter, NFCTag, NFCPeer,
+    tag,
+    peer,
+    isPeerConnected = false,
+    _data = {
+        INTERVAL : 1000,
+        listener : {
+            onTagDetected : null,
+            onPeerDetected : null,
+            onNDEFReceived : null
+        },
+        pairedNFC : null,
+        nfcAdapter : {},
+        nfcTags : [],
+        nfcTag: {},
+        nfcPeer : {},
+        isNear : false,     // Identify the device is whether near
+        isDetectTag : false, // Identify NFC tag is detected
+        connectedState : false
+    },
+    _security = {
+        "http://tizen.org/api/nfc": [],
+        "http://tizen.org/api/nfc.tag": ["setTagListener", "unsetTagListener", "getCachedMessage", "readNDEF", "writeNDEF", "transceive", "formatNDEF"],
+        "http://tizen.org/api/nfc.p2p": ["setPeerListener", "unsetPeerListener", "setReceiveNDEFListener", "unsetReceiveNDEFListener", "sendNDEF"],
+        all: true
+    },
+    _self;
+
+
+//validate the type match
+function _validateCallbackType(onSuccess, onError) {
+    if (onSuccess &&
+        typeof onSuccess !== "function" &&
+        typeof onSuccess !== "object") {
+        throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+    }
+    if (onError) {
+        tizen1_utils.validateArgumentType(onError, "function",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+    }
+    tizen1_utils.validateArgumentType(onSuccess.onattach, "function",
+        new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+    tizen1_utils.validateArgumentType(onSuccess.ondetach, "function",
+        new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+}
+
+_self = function () {
+    function getDefaultAdapter() {
+        if (arguments.length > 0)
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (!_data.nfcAdapter)
+            throw new WebAPIError(errorcode.UNKNOWN_ERR);
+
+        return _data.nfcAdapter;
+    }
+
+    function handleSubFeatures(subFeatures) {
+        for (var subFeature in subFeatures) {
+            if (_security[subFeature].length === 0) {
+                _security.all = true;
+                return;
+            }
+            _security.all = false;
+            utils.forEach(_security[subFeature], function (method) {
+                _security[method] = true;
+            });
+        }
+    }
+
+    var nfc = {
+        getDefaultAdapter: getDefaultAdapter,
+        handleSubFeatures: handleSubFeatures
+    };
+
+    nfc.__defineGetter__("NFC_RECORD_TNF_EMPTY", function () {
+        return 0;
+    });
+
+    nfc.__defineGetter__("NFC_RECORD_TNF_WELL_KNOWN", function () {
+        return 1;
+    });
+
+    nfc.__defineGetter__("NFC_RECORD_TNF_MIME_MEDIA", function () {
+        return 2;
+    });
+
+    nfc.__defineGetter__("NFC_RECORD_TNF_URI", function () {
+        return 3;
+    });
+
+    nfc.__defineGetter__("NFC_RECORD_TNF_EXTERNAL_RTD", function () {
+        return 4;
+    });
+
+    nfc.__defineGetter__("NFC_RECORD_TNF_UNKNOWN", function () {
+        return 5;
+    });
+
+    nfc.__defineGetter__("NFC_RECORD_TNF_UNCHANGED", function () {
+        return 6;
+    });
+
+    return nfc;
+};
+
+
+NFCAdapter = function () {
+    var nfcAdapter,
+        interval,
+        powered = false, // Identify the device on or off
+        polling = false; // Identify the device is polled
+        
+    event.trigger("nfc-power-changed", [powered]);
+    event.trigger("nfc-polling-changed", [polling]);
+    event.on("nfc-power-setting", function (status) {
+        _updatePowerStatus(status);   
+    });
+    event.on("nfc-polling-setting", function (status) {
+        _updatePollingStatus(status);   
+    });
+    event.on("nfc-attach-setting", function (type, isAttached) {
+        var isDetectTag;
+        isDetectTag = type === "Tag" ? true : false;
+        _updateIsNear(isDetectTag, isAttached);
+    });
+    event.on("nfc-tag-send", function (status) {
+        if (status) {
+            tag = db.retrieveObject(_NFC_TAG);
+            if (tag.isSupportedNDEF) {
+                _data.nfcTag = new NFCTag(tag.type, tag.isSupportedNDEF, tag.ndefSize, null, true, tag.ndefs);
+            } else {
+                _data.nfcTag = new NFCTag(tag.type, tag.isSupportedNDEF, tag.ndefSize, null, true, tag.rawData);
+            }
+            if (_data.listener.onTagDetected) {
+                _data.listener.onTagDetected.onattach(_data.nfcTag);
+            }
+        } else {
+            tag = {};
+            if (_data.listener.onTagDetected) {
+                _data.listener.onTagDetected.ondetach();
+            }
+        }
+    });
+    event.on("nfc-peer-send", function (status) {
+        if (status) {
+            _data.nfcPeer = new NFCPeer(true);
+            if (_data.listener.onPeerDetected) {
+                _data.listener.onPeerDetected.onattach(_data.nfcPeer);
+            }
+            isPeerConnected = true;
+        } else {
+            if (_data.listener.onPeerDetected) {
+                _data.listener.onPeerDetected.ondetach();
+            }
+            isPeerConnected = false;
+        }
+    });
+    event.on("nfc-peer-sending-ndef", function () {
+        if (isPeerConnected) {
+            peer = db.retrieveObject(_NFC_PEER);
+            if (_data.listener.onNDEFReceived) {
+                _data.listener.onNDEFReceived(peer.ndef);
+            }
+        }
+    });
+
+    // private
+    function _updatePowerStatus(status) {
+        if (powered === status) {
+            return;
+        }
+        if (!status) {
+            _updatePollingStatus(false);
+            _updateIsNear(_data.isDetectTag, false);
+            _data.listener.onTagDetected = null;
+            _data.listener.onPeerDetected = null;
+            _data.listener.onNDEFReceived = null;
+        }
+        powered = status;
+        event.trigger("nfc-power-changed", [powered]);
+    }
+    function _updatePollingStatus(status) {
+        if (!powered)
+            return;
+        if (polling === status) {
+            return;
+        }
+        polling = status;
+        event.trigger("nfc-polling-changed", [polling]);
+        if (polling) {
+            interval = setInterval(poll, _data.INTERVAL);
+        } else {
+            clearInterval(interval);
+        }
+    }
+    function _updateIsNear(isDetectTag, isAttached) {
+        _data.isDetectTag = isDetectTag;
+        _data.isNear = isAttached;
+        if (!_data.isNear) {
+            _data.connectedState = false;
+            event.trigger("nfc-connectedState-changed", [false]);
+        }
+    }
+    function poll() {
+        if (!_data.isNear) {
+            return;
+        }
+        if (!_data.connectedState) {
+            _data.connectedState = true;
+            event.trigger("nfc-connectedState-changed", [true]);
+
+        }
+    }
+
+    // public
+    // Turns NFC adapter on or off.
+    function setPowered(state, successCallback, errorCallback) {
+        tizen1_utils.validateArgumentType(state, "boolean",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        _updatePowerStatus(state);
+        successCallback(powered);
+    }
+
+    // Starts/stops polling for targets.
+    function setPolling(state, successCallback, errorCallback) {
+        tizen1_utils.validateArgumentType(state, "boolean",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        _updatePollingStatus(state);
+        successCallback(polling);
+    }
+
+    // Registers a callback function to invoke when NFC tag is detected.
+    function setTagListener(detectCallback, errorCallback, tagFilter) {
+
+        if (!_security.all && !_security.setTagListener)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        _validateCallbackType(detectCallback, errorCallback);
+
+        if (tagFilter) {
+            tizen1_utils.validateArgumentType(tagFilter, "array",
+                new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (!powered) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+        _data.listener.onTagDetected = detectCallback;
+    }
+
+    // Registers a callback function to be invoked when NFC peer-to-peer target is detected.
+    function setPeerListener(detectCallback, errorCallback) {
+        if (!_security.all && !_security.setPeerListener)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        _validateCallbackType(detectCallback, errorCallback);
+
+        if (!polling) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+        _data.listener.onPeerDetected = detectCallback;
+    }
+
+    // Unregisters the listener for detecting an NFC tag.
+    function unsetTagListener() {
+        if (!_security.all && !_security.unsetTagListener)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        if (!polling || !_data.listener.onTagDetected)
+            return;
+
+        _data.listener.onTagDetected = null;
+    }
+
+    // Unregisters the listener for detecting an NFC peer-to-peer target.
+    function unsetPeerListener() {
+        if (!_security.all && !_security.unsetPeerListener)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        if (!polling || !_data.listener.onPeerDetected)
+            return;
+
+        _data.listener.onPeerDetected = null;
+    }
+
+    // Gets NDEF message cached when the tag is detected.
+    function getCachedMessage() {
+        if (!_security.all && !_security.getCachedMessage)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        return _data.pairedNFC || {
+            recordCount : 0,
+            records : [],
+            toByte : function () {
+                var result = [], i;
+                for (i in this.records) {
+                    result = result.concat(this.records[i].payload);
+                }
+                return result;
+            }
+        };
+    }
+
+    nfcAdapter = {
+        setPowered : setPowered,
+        setPolling : setPolling,
+        setTagListener : setTagListener,
+        setPeerListener : setPeerListener,
+        unsetTagListener : unsetTagListener,
+        unsetPeerListener : unsetPeerListener,
+        getCachedMessage : getCachedMessage
+    };
+
+    nfcAdapter.__defineGetter__("powered", function () {
+        return powered;
+    });
+
+    nfcAdapter.__defineGetter__("polling", function () {
+        return polling;
+    });
+
+    return nfcAdapter;
+};
+
+NFCTag = function (type, isSupportedNDEF, ndefSize, properties, isConnected, ndefs) {
+    var nfcTag,
+        _ndefs,
+        _ndefs_index = 0;
+        
+    type = type || null;
+    isSupportedNDEF = isSupportedNDEF || false;
+    ndefSize = ndefSize || 1;
+    properties = null;
+    isConnected = isConnected || false;
+    _ndefs = ndefs || [];
+
+    // Reads NDEF data.
+    function readNDEF(readCallback, errorCallback) {
+        function _readNDEF() {
+            if (!isConnected || !isSupportedNDEF) {
+                if (errorCallback) {
+                    errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+                }
+                return;
+            }
+            if (_ndefs_index >= ndefSize) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            } else {
+                readCallback(_ndefs[_ndefs_index]);
+                _ndefs_index++;
+            }
+        }
+
+        if (!_security.all && !_security.readNDEF)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        tizen1_utils.validateTypeMismatch(readCallback, errorCallback, "nfc:readNDEF", _readNDEF);
+    }
+
+    // Writes NDEF data.
+    function writeNDEF(ndefMessage, successCallback, errorCallback) {
+        if (!_security.all && !_security.writeNDEF)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        tizen1_utils.validateArgumentType(ndefMessage, "object",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+
+        if (!isConnected || !isSupportedNDEF) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+        db.saveObject(_NFC_OUTPUT_MESSAGE, ndefMessage);
+        event.trigger("nfc-output-msg", []);
+        if (successCallback) {
+            successCallback();
+        }
+    }
+
+    // Access the raw format card.
+    function transceive(data, dataCallback, errorCallback) {
+        function _transceive() {
+            if (!tizen1_utils.isValidArray(data))
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+            if (!isConnected || isSupportedNDEF) {
+                if (errorCallback) {
+                    errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+                }
+                return;
+            }
+            db.saveObject(_NFC_OUTPUT_MESSAGE, data);
+            event.trigger("nfc-output-msg", []);
+            dataCallback(_ndefs);
+        }
+
+        if (!_security.all && !_security.transceive)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        tizen1_utils.validateTypeMismatch(dataCallback, errorCallback, "nfc:transceive", _transceive);
+    }
+
+    // Formats the detected tag that can store NDEF messages.
+    function formatNDEF(successCallback, errorCallback, key) {
+        if (!_security.all && !_security.formatNDEF)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        if (key) {
+            tizen1_utils.validateArgumentType(key, "array",
+                new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+
+        if (!isConnected || !isSupportedNDEF) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+
+        successCallback();
+    }
+
+    nfcTag = {
+        readNDEF : readNDEF,
+        writeNDEF : writeNDEF,
+        transceive : transceive,
+        formatNDEF : formatNDEF
+    };
+
+    nfcTag.__defineGetter__("type", function () {
+        return type;
+    });
+
+    nfcTag.__defineGetter__("isSupportedNDEF", function () {
+        return isSupportedNDEF;
+    });
+
+    nfcTag.__defineGetter__("ndefSize", function () {
+        return ndefSize;
+    });
+
+    nfcTag.__defineGetter__("properties", function () {
+        return properties;
+    });
+
+    nfcTag.__defineGetter__("isConnected", function () {
+        return isConnected;
+    });
+
+    return nfcTag;
+};
+
+NFCPeer = function (isConnected) {
+    var nfcPeer;
+
+    isConnected = isConnected || false;
+
+    // Registers a callback function to be invoked when NDEF message is received from NFC peer-to-peer target connected.
+    function setReceiveNDEFListener(successCallback, errorCallback) {
+        function _setReceiveNDEFListener() {
+            if (!isConnected) {
+                if (errorCallback) {
+                    errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+                }
+                return;
+            }
+            _data.listener.onNDEFReceived = successCallback;
+        }
+
+        if (!_security.all && !_security.setReceiveNDEFListener)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "nfc:setReceiveNDEFListener", _setReceiveNDEFListener);
+    }
+
+    // Unregisters the listener for receiving NDEFMessage from NFC peer-to-peer target connected.
+    function unsetReceiveNDEFListener() {
+        if (!_security.all && !_security.unsetReceiveNDEFListener)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        _data.listener.onNDEFReceived = null;
+    }
+
+    // Sends data to NFC peer-to-peer target.
+    function sendNDEF(ndefMessage, successCallback, errorCallback) {
+        if (!_security.all && !_security.sendNDEF)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        tizen1_utils.validateArgumentType(ndefMessage, "object",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+
+        if (!isConnected) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+
+        db.saveObject(_NFC_OUTPUT_MESSAGE, ndefMessage);
+        event.trigger("nfc-output-msg", []);
+        if (successCallback) {
+            successCallback();
+        }
+    }
+
+    nfcPeer = {
+        setReceiveNDEFListener : setReceiveNDEFListener,
+        unsetReceiveNDEFListener : unsetReceiveNDEFListener,
+        sendNDEF : sendNDEF
+    };
+
+    nfcPeer.__defineGetter__("isConnected", function () {
+        return isConnected;
+    });
+
+    return nfcPeer;
+};
+
+function _initialize() {
+    _data.nfcAdapter = new NFCAdapter();
+}
+_initialize();
+
+module.exports = _self;
+
+
+});
+require.define('ripple/platform/tizen/1.0/AccountBase', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (providerId, accountInit) {
+    var _self,
+        _id = Math.uuid(null, 16),
+        _providerId = String(providerId);
+
+    _self = {
+        displayName : null,
+        icon : null,
+        enabled : true,
+        credentialId : null,
+        services : [],
+        settings : null
+    };
+
+    _self.__defineGetter__("id", function () {
+        return _id;
+    });
+
+    _self.__defineGetter__("providerId", function () {
+        return _providerId;
+    });
+
+    if (accountInit) {
+        _self.displayName = String(accountInit.displayName);
+        _self.icon        = String(accountInit.iconPath);
+    }
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/navigator', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _original = window.navigator,
+    utils = require('ripple/utils'),
+    devices = require('ripple/devices'),
+    constants = require('ripple/constants'),
+    vibration = require('ripple/platform/tizen/1.0/vibration'),
+    _self = {};
+
+(function () {
+    var key,
+        nav = window.navigator;
+
+    function _handle(obj, key) {
+        return typeof obj[key] !== "function" ? obj[key] : function () {
+            return obj[key].apply(obj, Array.prototype.slice.call(arguments));
+        };
+    }
+
+    for (key in nav) {
+        _self[key] = _handle(nav, key);
+    }
+}());
+
+_self.__defineGetter__('userAgent', function () {
+    var currentUserAgent = devices.getCurrentDevice().userAgent;
+
+    return currentUserAgent === constants.COMMON.USER_AGENT_DEFAULT ?
+        _original.userAgent : currentUserAgent;
+});
+
+_self.__defineGetter__('vibrate', function () {
+    return vibration.vibrate;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/call', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    event = require('ripple/event'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    _history,
+    _currentServiceIndex = 0,
+    _data = {
+        DB_CALL_KEY: "tizen1-db-call",
+        isCallInProgress: false,
+        observers: {},
+        callServices: [],
+        callHistory: []
+    },
+    _security = {
+        "http://tizen.org/api/call": [],
+        "http://tizen.org/api/call.simple": ["getCallServices", "isCallInProgress"],
+        "http://tizen.org/api/call.history": ["history"],
+        "http://tizen.org/api/call.history.read": ["find", "addListener", "removeListener"],
+        "http://tizen.org/api/call.history.write": ["CallHistoryEntry", "remove", "removeBatch", "removeAll"],
+        all: true
+    },
+    CALL_SERVICE_TYPE = ["tizen.tel", "tizen.xmpp", "tizen.sip"],
+    CALL_SERVICE_TAG = ["call", "call.voice", "call.video", "call.emergency"],
+    _RECORDING_KEY = "tizen1-call-recording",
+    _RECORDING_PATH = "music/",
+    _self;
+
+function _getValue(inputValue, key) {
+    var keys = key.split("."),
+        value = inputValue[keys[0]],
+        index;
+
+    for (index = 1; index < keys.length; index++) {
+        if (value[keys[index]]) {
+            value = value[keys[index]];
+        }
+    }
+
+    return value;
+}
+
+function _filter(inputArray, filter) {
+    var index, filterResults = [], compositeResultArray;
+
+    if (filter === null || filter === undefined) {
+        return inputArray;
+    }
+
+    if (filter.attributeName === null || filter.attributeName === undefined) {
+        throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+    }
+
+    if (filter.matchFlag) {
+        filterResults = tizen1_utils.matchAttributeFilter(inputArray, filter.attributeName, filter.matchFlag, filter.matchValue);
+    }
+    else if (filter.initialValue || filter.endValue) {
+        filterResults = tizen1_utils.matchAttributeRangeFilter(inputArray, filter.attributeName, filter.initialValue, filter.endValue);
+    }
+    else if (filter.type && filter.filters) {
+        for (index = 0; index < filter.filters.length; index++) {
+            compositeResultArray = _filter(inputArray, filter.filters[index]);
+
+            filterResults = tizen1_utils.arrayComposite(filter.type, filterResults, compositeResultArray);
+        }
+    }
+
+    return filterResults;
+}
+
+function _sort(inputArray, sortMode) {
+    if (sortMode.attributeName === null || sortMode.attributeName === undefined) {
+        throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+    }
+
+    inputArray.sort(function (a, b) {
+        return sortMode.order === "DESC" ? _getValue(a, sortMode.attributeName) - _getValue(b, sortMode.attributeName) :
+               _getValue(b, sortMode.attributeName) - _getValue(a, sortMode.attributeName);
+    });
+
+    return inputArray;
+}
+
+function _save() {
+    db.saveObject(_data.DB_CALL_KEY, _data.callHistory);
+}
+
+function _retrive() {
+    var callHistoryList, callHistory, index;
+    
+    if (_data.callHistory.length === 0) {
+        callHistoryList = db.retrieveObject(_data.DB_CALL_KEY) || [];
+
+        for (index = 0; index < callHistoryList.length; index++) {
+            callHistory = callHistoryList[index];
+            _data.callHistory.push(_getCallHistoryEntry(callHistory.serviceId, callHistory.callType, callHistory.tags,
+                                       callHistory.callParticipants, callHistory.forwardedFrom, 
+                                       callHistory.startTime, callHistory.duration, callHistory.endReason,
+                                       callHistory.direction, callHistory.recording, callHistory.cost, callHistory.currency));
+        }
+    }
+
+    return tizen1_utils.copy(_data.callHistory);
+}
+
+function _deleteRecording(id) {
+    var path = _RECORDING_PATH + id + ".mp3",
+        recording = [];
+
+    recording = db.retriveObject(_RECORDING_KEY);
+    recording = recording.filter(function (element) {
+        return element !== path;
+    });
+    
+    db.saveObject(_RECORDING_KEY, recording);
+}
+
+function _isCallHistoryEntryType(arg) {
+    return arg && arg.hasOwnProperty("serviceId") && arg.hasOwnProperty("callType") &&
+           arg.hasOwnProperty("tags") && arg.hasOwnProperty("callParticipants") && 
+           arg.hasOwnProperty("forwardedFrom") && arg.hasOwnProperty("startTime") &&
+           arg.hasOwnProperty("duration") && arg.hasOwnProperty("endReason") &&
+           arg.hasOwnProperty("direction") && arg.hasOwnProperty("recording") && 
+           arg.hasOwnProperty("cost") && arg.hasOwnProperty("currency");
+}
+
+function _isCallServiceFilterType(arg) {
+    if (arg && arg.hasOwnProperty("serviceTypeId") && !utils.arrayContains(CALL_SERVICE_TYPE, arg["serviceTypeId"])) {
+        return false;
+    }
+
+    if (arg && arg.hasOwnProperty("tags")) {
+        if (!tizen1_utils.isValidArray(arg["tags"])) {
+            return false;
+        }
+        else if (arg["tags"].some(function (element) {
+            return !utils.arrayContains(CALL_SERVICE_TAG, element);
+        })) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+function _getRemoteParty(remoteParty, displayName, contactRef) {
+    var _contactRef = tizen1_utils.copy(contactRef),
+        _self = {};
+
+    _self.__defineGetter__("remoteParty", function () {
+        return remoteParty;
+    });
+
+    _self.__defineGetter__("displayName", function () {
+        return displayName;
+    });
+
+    _self.__defineGetter__("contactRef", function () {
+        return _contactRef;
+    });
+
+    return _self;
+}
+
+function _getCallHistoryEntry(serviceId, callType, tags, callParticipants,
+                              forwardedFrom, startTime, duration, endReason,
+                              direction, recording, cost, currency) {
+    var _tags = tizen1_utils.copy(tags),
+        _callParticipants = [],
+        _forwardedFrom = forwardedFrom ? _getRemoteParty(forwardedFrom.remoteParty, forwardedFrom.displayName, forwardedFrom.contactRef) : {},
+        _startTime = new Date(startTime),
+        _recording = tizen1_utils.copy(recording),
+        _self = {},
+        participantItem,
+        index;
+
+    for (index = 0; index < callParticipants.length; index++) {
+        participantItem = callParticipants[index];
+        _callParticipants.push(_getRemoteParty(participantItem.id, participantItem.displayName, participantItem.contactRef));
+    }
+
+    _self.__defineGetter__("serviceId", function () {
+        return serviceId;
+    });
+
+    _self.__defineGetter__("callType", function () {
+        return callType;
+    });
+
+    _self.__defineGetter__("tags", function () {
+        return _tags;
+    });
+
+    _self.__defineGetter__("callParticipants", function () {
+        return _callParticipants;
+    });
+
+    _self.__defineGetter__("forwardedFrom", function () {
+        return _forwardedFrom;
+    });
+
+    _self.__defineGetter__("startTime", function () {
+        return _startTime;
+    });
+
+    _self.__defineGetter__("duration", function () {
+        return duration;
+    });
+
+    _self.__defineGetter__("endReason", function () {
+        return endReason;
+    });
+
+    _self.direction = direction;
+
+    _self.__defineGetter__("recording", function () {
+        return _recording;
+    });
+
+    _self.__defineGetter__("cost", function () {
+        return cost;
+    });
+
+    _self.currency = currency;
+
+    return _self;
+}
+
+function AccountServiceClass(serviceName, serviceTypeId, providerId, tags) {
+    var _self = {
+        serviceName: serviceName,
+        serviceTypeId: serviceTypeId,
+        providerId: providerId,
+        tags: tags
+    };
+
+    this.__defineGetter__("serviceName", function () {
+        return _self.serviceName;
+    });
+    this.__defineGetter__("serviceTypeId", function () {
+        return _self.serviceTypeId;
+    });
+    this.__defineGetter__("providerId", function () {
+        return _self.providerId;
+    });
+    this.__defineGetter__("tags", function () {
+        return _self.tags;
+    });
+
+    this.applicationId = "";
+    this.displayName = "";
+    this.icon = "";
+    this.enabled = false;
+    this.settings = "";
+}
+
+function AccountService() {
+    var _self = {
+        id: "",
+        accountId: ""
+    };
+
+    if (arguments.length >= 4) {
+        AccountServiceClass.call(this, arguments[0], arguments[1], arguments[2], arguments[3]);
+    }
+    else {
+        AccountServiceClass.call(this);
+    }
+
+    this.__defineGetter__("id", function () {
+        return _self.id;
+    });
+    this.__defineGetter__("accountId", function () {
+        return _self.accountId;
+    });
+}
+
+function CallService() {
+    if (arguments.length >= 4) {
+        AccountService.call(this, arguments[0], arguments[1], arguments[2], arguments[3]);
+    }
+    else {
+        AccountService.call(this);
+    }
+
+    this.launchDialer = function (remoteParty, successCallback, errorCallback, extension) {
+        if (remoteParty === null || remoteParty === undefined) {
+            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+        }
+
+        if ((successCallback && typeof successCallback !== "function") || 
+            (errorCallback && typeof errorCallback !== "function")) {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+
+        // The ui pannel will respnd this event and launch the dailer panel
+        event.trigger("DialerLaunched", [remoteParty]);
+    };
+
+    this.__defineGetter__("voicemailNumbers", function () {
+        return "13800100200";
+    });
+}
+
+function CellularCallService() {
+    var subscriberNumbers = ["10086"],
+        emergencyNumbers = ["110", "911", "120"];
+
+    if (arguments.length >= 4) {
+        CallService.call(this, arguments[0], arguments[1], arguments[2], arguments[3]);
+    }
+    else {
+        CallService.call(this);
+    }
+
+    this.sendUSSD = function (command, successCallback, errorCallback) {
+        var response = "";
+    
+        if (command === null || command === undefined) {
+            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+        }
+
+        if ((successCallback && typeof successCallback !== "function") ||
+            (errorCallback && typeof errorCallback !== "function")) {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+
+        if (command === "*#06#") {
+            response = "352099001761482";
+        }
+        else {
+            response = "simulated USSD response";
+        }
+
+        setTimeout(successCallback(response), 1);
+    };    
+
+    this.__defineGetter__("subscriberNumbers", function () {
+        return subscriberNumbers;
+    });
+
+    this.__defineGetter__("emergencyNumbers", function () {
+        return emergencyNumbers;
+    });
+}
+
+function CallHistory() {
+    this.find = function (successCallback, errorCallback, filter, sortMode, limit, offset) {
+        var callHistory = _retrive(),
+            filterResults = callHistory,
+            limitValue = limit | 0,
+            offsetValue = offset | 0;
+
+            if (!_security.all && !_security.history && !_security.find) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            if (successCallback === null || successCallback === undefined) {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+
+            if (typeof successCallback !== "function" || (errorCallback && typeof errorCallback !== "function")) {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+
+        setTimeout(function () {
+            if (filter) {
+                filterResults = _filter(callHistory, filter);
+            }
+            
+            if (sortMode) {
+                _sort(filterResults, sortMode);
+            }
+
+            if (limitValue > 0) {
+                offsetValue = offsetValue > 0 ? offsetValue : 0;
+                filterResults = filterResults.slice(offsetValue, limitValue);
+            }
+
+            successCallback(filterResults);
+        }, 1);
+    };
+    this.remove = function (entry) {
+        var isFound = false;
+
+        if (!_security.all && !_security.history && !_security.remove) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        if (!_isCallHistoryEntryType(entry)) {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+
+        _data.callHistory = _data.callHistory.filter(function (element) {
+            return utils.some(element, function (value, key) {
+                if (tizen1_utils.isEqual(entry[key], value)) {
+                    isFound = true;
+                    return false;
+                }
+                return true;
+            });
+        });
+
+        if (!isFound) {
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+        }
+
+        _save();
+    };
+    this.removeBatch = function (entries, successCallback, errorCallback) {
+        var isFound = false, index;
+
+        if (!_security.all && !_security.history && !_security.removeBatch) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        if ((successCallback && typeof successCallback !== "function") ||
+            (errorCallback && typeof errorCallback !== "function")) {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+
+        for (index = 0; index < entries.length; index++) {
+            if (!_isCallHistoryEntryType(entries[index])) {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+        }
+
+        setTimeout(function () {
+            isFound = entries.every(function (element) {
+                return _data.callHistory.some(function (callHistory) {
+                    return tizen1_utils.isEqual(element, callHistory);
+                });
+            });
+
+            if (!isFound) {
+                if (errorCallback) {
+                    errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                    return;
+                }
+                else {
+                    throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+                }
+            }
+
+            _data.callHistory = _data.callHistory.filter(function (element) {
+                return !entries.some(function (entryValue, entryIndex) {
+                    return tizen1_utils.isEqual(element, entryValue);
+                });
+            });
+        
+            _save();
+
+            if (successCallback) {
+                successCallback(_retrive());
+            }
+        }, 1);
+    };
+    this.removeAll = function (successCallback, errorCallback) {
+        var removedEntries = [];
+
+        if (!_security.all && !_security.history && !_security.removeAll) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        if ((successCallback && typeof successCallback !== "function") ||
+            (errorCallback && typeof errorCallback !== "function")) {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+
+        removedEntries = _retrive();
+        _data.callHistory = [];
+        _save();
+
+        if (successCallback) {
+            successCallback(removedEntries);
+        }
+    };
+    this.deleteRecording = function (historyEntry, successCallback, errorCallback) {
+        var isFound = false;
+
+        if (!_security.all && !_security.history && !_security.deleteRecording) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        if ((successCallback && typeof successCallback !== "function") ||
+            (errorCallback && typeof errorCallback !== "function")) {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+
+        if (!_isCallHistoryEntryType(historyEntry) || historyEntry["recording"] === null) {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+
+        isFound = _data.callHistory.some(function (callHistory, index) {
+            if (tizen1_utils.isEqual(historyEntry, callHistory)) {
+                _data.callHistory[index]["recording"] = null;
+                return true;
+            }
+            return false;
+        });
+
+        if (!isFound) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                return;
+            }
+            else {
+                throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+            }
+        }
+
+        _deleteRecording(historyEntry.serviceId);
+        _save();
+
+        if (successCallback) {
+            successCallback(_retrive());
+        }
+
+        utils.forEach(_data.observers, function (observer) {
+            observer.onchanged(historyEntry);
+        });
+    };
+    this.addListener = function (observerObj) {
+        var handle = Math.uuid(null, 16);
+
+        if (!_security.all && !_security.history && !_security.addListener) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        if ((observerObj === null || observerObj === undefined) || !observerObj.hasOwnProperty("onadded") ||
+            !observerObj.hasOwnProperty("onchanged")) {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+
+        if (typeof observerObj.onadded !== "function" || typeof observerObj.onchanged !== "function") {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+
+        _data.observers[handle] = observerObj;
+
+        return handle;
+    };
+    this.removeListener = function (handle) {
+        if (!_security.all && !_security.history && !_security.removeListener) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        if (_data.observers[handle]) {
+            delete _data.observers[handle];
+        }
+        else {
+            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+        }
+    };
+}
+
+function _initialize() {
+    _data.callServices.push(new CallService("TelVoice1", "tizen.tel", "VTMobile", ["call.voice", "call.video"]));
+    _data.callServices.push(new CallService("TelEmergency1", "tizen.xmpp", "VTUnicom", ["call.voice", "call.emergency"]));
+    _data.callServices.push(new CallService("Telephone1", "tizen.sip", "VTComm", ["call"]));
+
+    _history = new CallHistory();
+    _retrive();
+
+    event.on("CallInProgress", function (isInProgress) {
+        _data.isCallInProgress = isInProgress;
+    });
+
+    event.on("CallRecorded", function (record) {
+        var callService = _data.callServices[_currentServiceIndex],
+            historyEntry = _getCallHistoryEntry(record.serviceId, callService.serviceTypeId, callService.tags,
+                               record.callParticipants, record.forwardedFrom, record.startTime, record.duration, 
+                               record.endReason, record.direction, record.recording, 0, null);
+
+        _data.callHistory.push(historyEntry);
+        _save();
+
+        utils.forEach(_data.observers, function (observer) {
+            observer.onadded([historyEntry]);
+        });
+    });
+}
+
+_self = {
+    history: undefined,
+    isCallInProgress: function () {
+        if (!_security.all && !_security.isCallInProgress) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        return _data.isCallInProgress;
+    },
+    getCallServices: function (filter) {
+        if (!_security.all && !_security.getCallServices) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        if (!_isCallServiceFilterType(filter)) {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+
+        _data.callServices = _data.callServices.filter(function (element) {
+            var flag = true;
+            utils.forEach(filter, function (value, key) {
+                if (!tizen1_utils.isEqual(element[key], value)) {
+                    flag = false;
+                }
+            });
+
+            return flag;
+        });
+
+        return _data.callServices;
+    },
+    handleSubFeatures: function (subFeatures) {
+        function setSecurity(_security) {
+            return function (method) {
+                _security[method] = true;
+            };
+        }
+
+        for (var subFeature in subFeatures) {
+            if (_security[subFeature].length === 0) {
+                _security.all = true;
+                return;
+            }
+            _security.all = false;
+            utils.forEach(_security[subFeature], setSecurity);
+        }
+    }
+};
+
+_self.__defineGetter__("history", function () {
+    return _history;
+});
+
+_initialize();
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/AttributeFilter', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (_attributeName, _matchFlag, _matchValue) {
+    return {
+        attributeName: _attributeName,
+        matchFlag: _matchFlag,
+        matchValue: _matchValue
+    };
+};
+
+});
+require.define('ripple/platform/tizen/1.0/ContactEmailAddress', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+var tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils');
+
+module.exports = function (email, types) {
+    var _self, _email = "", i,
+        _types = [], type;
+    
+    if (email) {
+        _email = String(email);
+    }
+    if (tizen1_utils.isValidArray(types)) {
+        for (i = 0; i < types.length; i++) {
+            type = String(types[i]).toUpperCase();
+            _types.push(type);
+        }
+    }
+
+    _self = {
+        email : _email,
+        types : _types
+    };
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/account', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    _data = {
+        DB_ACCOUNT_KEY : "tizen1-db-accounts",
+        accountServiceProviders : [],
+        accountServiceTypes : [],
+        accountServiceClasses : [],
+        accounts : [],
+        listeners : {}
+    },
+    _self;
+
+function _isValid(filter, enable) {
+    if (filter &&
+        ((typeof filter !== "object") ||
+        (filter.serviceTypeId !== undefined) && (typeof filter.serviceTypeId !== "string") ||
+        (filter.providerId !== undefined) && (typeof filter.providerId !== "string") ||
+        (filter.tags !== undefined) && (!filter.tags instanceof Array)))
+        return false;
+
+    if ((enable !== undefined) && (enable !== null) && (typeof enable !== "boolean"))
+        return false;
+
+    return true;
+}
+
+function _checkServiceClass(serviceClass, filter) {
+    var retCheck = true, count = 0, i, j;
+
+    if ((filter.serviceTypeId !== undefined) && (filter.serviceTypeId !== serviceClass.serviceTypeId)) {
+        retCheck = false;
+    } else if ((filter.providerId !== undefined) && (filter.providerId !== serviceClass.providerId)) {
+        retCheck = false;
+    } else if ((filter.tags !== undefined) && (filter.tags.length !== 0)) {
+        if (serviceClass.tags === undefined || serviceClass.tags.length === 0) {
+            retCheck = false;
+        } else {
+            for (i in filter.tags) {
+                for (j in serviceClass.tags) {
+                    if (filter.tags[i] === serviceClass.tags[j]) {
+                        count++;
+                        break;
+                    }
+                }
+            }
+            if (count !== filter.tags.length) {
+                retCheck = false;
+            }
+        }
+    }
+    return retCheck;
+}
+
+function _sortNumber(a, b) {
+    return b - a;
+}
+
+_self = {
+    getAccountById : function (id) {
+        var account = null, count;
+
+        if (typeof id !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        for (count in _data.accounts) {
+            if (_data.accounts[count].id === id) {
+                account = utils.copy(_data.accounts[count]);
+                break;
+            }
+        }
+        return account;
+    },
+
+    getServiceById : function (id) {
+        var accountService = null, count;
+
+        if (typeof id !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        for (count in _data.accountServiceClasses) {
+            if (_data.accountServiceClasses[count].id === id) {
+                accountService = utils.copy(_data.accountServiceClasses[count]);
+                break;
+            }
+        }
+        return accountService;
+    },
+
+    getServiceClassByName : function (name) {
+        var accountServiceClass = null, count;
+
+        if (typeof name !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        for (count in _data.accountServiceClasses) {
+            if ((_data.accountServiceClasses[count].id === undefined) &&
+                (_data.accountServiceClasses[count].serviceName === name)) {
+                accountServiceClass = utils.copy(_data.accountServiceClasses[count]);
+                break;
+            }
+        }
+        return accountServiceClass;
+    },
+
+    getServiceTypeById : function (id) {
+        var accountServiceType = null, count;
+
+        if (typeof id !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        for (count in _data.accountServiceTypes) {
+            if (_data.accountServiceTypes[count].id === id) {
+                accountServiceType = utils.copy(_data.accountServiceTypes[count]);
+                break;
+            }
+        }
+        return accountServiceType;
+    },
+
+    getProviderById : function (id) {
+        var accountServiceProvider = null, count;
+
+        if (typeof id !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        for (count in _data.accountServiceProviders) {
+            if (_data.accountServiceProviders[count].id === id) {
+                accountServiceProvider = utils.copy(_data.accountServiceProviders[count]);
+                break;
+            }
+        }
+        return accountServiceProvider;
+    },
+
+    findAccounts : function (filter, enabled) {
+        var result = [], count, i;
+
+        if (!_isValid(filter, enabled))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (!filter) {
+            if (enabled === undefined || enabled === null) {
+                result = _data.accounts;
+            } else {
+                for (count in _data.accounts) {
+                    if (_data.accounts[count].enabled === enabled) {
+                        result.push(utils.copy(_data.accounts[count]));
+                    }
+                }
+            }
+        } else {
+            for (count in _data.accounts) {
+                if (_data.accounts[count].services === undefined || _data.accounts[count].services.length === 0) {
+                    continue;
+                }
+                for (i in _data.accounts[count].services) {
+                    if (_checkServiceClass(_data.accounts[count].services[i], filter) &&
+                        (enabled === undefined || _data.accounts[count].enabled === enabled)) {
+                        result.push(utils.copy(_data.accounts[count]));
+                        break;
+                    }
+                }
+            }
+        }
+
+        return result;
+    },
+
+    findServices : function (filter, enabled) {
+        var result = [], count;
+
+        if (!_isValid(filter, enabled))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (!filter) {
+            if (enabled === undefined || enabled === null) {
+                for (count in _data.accountServiceClasses) {
+                    if (_data.accountServiceClasses[count].id !== undefined) {
+                        result.push(_data.accountServiceClasses[count]);
+                    }
+                }
+            } else {
+                for (count in _data.accountServiceClasses) {
+                    if ((_data.accountServiceClasses[count].enabled === enabled) &&
+                        (_data.accountServiceClasses[count].id !== undefined)) {
+                        result.push(_data.accountServiceClasses[count]);
+                    }
+                }
+            }
+        } else {
+            for (count in _data.accountServiceClasses) {
+                if (_data.accountServiceClasses[count].id !== undefined) {
+                    if (_checkServiceClass(_data.accountServiceClasses[count], filter) &&
+                        (enabled === undefined || enabled === null || _data.accountServiceClasses[count].enabled === enabled) &&
+                        (_data.accountServiceClasses[count].id !== undefined)) {
+                        result.push(_data.accountServiceClasses[count]);
+                    }
+                }
+            }
+        }
+        if (result.length === 0)
+            result = null;
+
+        return result;
+    },
+
+    findProviders : function (serviceTypeId) {
+        var providerList = null, providerIds = [], count, i, j;
+
+        if (serviceTypeId && (typeof serviceTypeId !== "string"))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (!serviceTypeId) {
+            providerList = _data.accountServiceProviders;
+        } else {
+            for (count in _data.accountServiceClasses) {
+                if ((_data.accountServiceClasses[count].serviceTypeId === serviceTypeId) &&
+                    (_data.accountServiceClasses[count].id === undefined)) {
+                    providerIds.push(_data.accountServiceClasses[count].providerId);
+                }
+            }
+            if (providerIds.length !== 0) {
+                providerList = [];
+                for (i in _data.accountServiceProviders) {
+                    for (j in providerIds) {
+                        if (_data.accountServiceProviders[i].id === providerIds[j]) {
+                            providerList.push(_data.accountServiceProviders[i]);
+                        }
+                    }
+                }
+            }
+        }
+        return providerList;
+    },
+
+    findServiceTypes : function (prefix) {
+        var serviceTypeList = null, count;
+
+        if (prefix && (typeof prefix !== "string"))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (_data.accountServiceTypes.length !== 0) {
+            if (!prefix) {
+                serviceTypeList = _data.accountServiceTypes;
+            } else {
+                serviceTypeList = [];
+                for (count in _data.accountServiceTypes) {
+                    if (_data.accountServiceTypes[count].displayName.indexOf(prefix) !== -1) {
+                        serviceTypeList.push(_data.accountServiceTypes[count]);
+                    }
+                }
+            }
+        }
+        return serviceTypeList;
+    },
+
+    findServiceClasses : function (filter) {
+        var serviceClasses = [], count;
+
+        if (!_isValid(filter, undefined))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (_data.accountServiceClasses.length !== 0) {
+            if (!filter) {
+                for (count in _data.accountServiceClasses) {
+                    if (_data.accountServiceClasses[count].id === undefined) {
+                        serviceClasses.push(_data.accountServiceClasses[count]);
+                    }
+                }
+            } else {
+                for (count in _data.accountServiceClasses) {
+                    if (_checkServiceClass(_data.accountServiceClasses[count], filter) &&
+                        (_data.accountServiceClasses[count].id === undefined)) {
+                        serviceClasses.push(_data.accountServiceClasses[count]);
+                    }
+                }
+            }
+        }
+        if (serviceClasses.length === 0)
+            serviceClasses = null;
+
+        return serviceClasses;
+    },
+
+    addAccount : function (account) {
+        var count, att;
+
+        for (count in _data.accounts) {
+            if (_data.accounts[count].id === account.id)
+                return;
+        }
+        _data.accounts.push(utils.copy(account));
+        db.saveObject(_data.DB_ACCOUNT_KEY, _data.accounts);
+        for (att in _data.listeners) {
+            _data.listeners[att].onAccountAdded(account);
+        }
+    },
+
+    deleteAccount : function (accountId) {
+        var deleteList = [], count, subscript, i, att;
+
+        if (typeof accountId !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        for (count in _data.accounts) {
+            if (_data.accounts[count].id === accountId) {
+                _data.accounts.splice(count, 1);
+                if (_data.accountServiceClasses.length !== 0) {
+                    for (subscript in _data.accountServiceClasses) {
+                        if (_data.accountServiceClasses[subscript].accountId === accountId) {
+                            deleteList.push(i);
+                        }
+                    }
+                    if (deleteList.length !== 0) {
+                        deleteList.sort(_sortNumber);
+                        for (i = deleteList.length - 1; i >= 0; i--) {
+                            _data.accountServiceClasses.splice(i, 1);
+                        }
+                    }
+                }
+                db.saveObject(_data.DB_ACCOUNT_KEY, _data.accounts);
+                for (att in _data.listeners) {
+                    _data.listeners[att].onAccountRemoved(accountId);
+                }
+                return;
+            }
+        }
+        throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+    },
+
+    addAccountListener : function (observer, errorCallback) {
+        var handle;
+
+        if (typeof observer !== "object")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (observer.onAccountUpdated)
+            tizen1_utils.validateArgumentType(observer.onAccountUpdated, "function",
+                new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+
+        if (observer.onAccountAdded)
+            tizen1_utils.validateArgumentType(observer.onAccountAdded, "function",
+                new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+
+        if (observer.onAccountRemoved)
+            tizen1_utils.validateArgumentType(observer.onAccountRemoved, "function",
+                new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+
+        if (errorCallback && (typeof errorCallback !== "function"))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        do {
+            handle = Math.uuid(10, 10);
+        } while (handle.toString().indexOf('0') === 0);
+        _data.listeners[handle] = observer;
+
+        return handle;
+    },
+
+    removeAccountListener : function (handle) {
+        if (typeof handle !== "number")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (!_data.listeners[handle])
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        delete _data.listeners[handle];
+    },
+
+    registerServiceType : function (serviceTypeDeclaration, successCallback, errorCallback) {
+        var count;
+
+        if ((typeof successCallback !== "function") || (typeof errorCallback !== "function"))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if ((typeof serviceTypeDeclaration.id !== "string") ||
+            (typeof serviceTypeDeclaration.displayName !== "string") ||
+            (typeof serviceTypeDeclaration.icon !== "string") ||
+            (!serviceTypeDeclaration.tags instanceof Array))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        for (count in _data.accountServiceTypes) {
+            if (_data.accountServiceTypes[count].id === serviceTypeDeclaration.id) {
+                errorCallback();
+                return;
+            }
+        }
+
+        _data.accountServiceTypes.push(serviceTypeDeclaration);
+        successCallback(serviceTypeDeclaration);
+    },
+
+    registerServiceProvider : function (providerDeclaration, successCallback, errorCallback) {
+        var count;
+
+        if ((typeof successCallback !== "function") || (typeof errorCallback !== "function"))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if ((typeof providerDeclaration.id !== "string") ||
+            ((providerDeclaration.displayName !== undefined) && (typeof providerDeclaration.displayName !== "string")) ||
+            ((providerDeclaration.icon !== undefined) && (typeof providerDeclaration.icon !== "string")))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        for (count in _data.accountServiceProviders) {
+            if (providerDeclaration.id === _data.accountServiceProviders[count].id) {
+                errorCallback();
+                return;
+            }
+        }
+
+        _data.accountServiceProviders.push(providerDeclaration);
+        successCallback(providerDeclaration);
+    },
+
+    registerServiceClass : function (serviceDeclaration, successCallback, errorCallback) {
+        var count;
+
+        if ((typeof successCallback !== "function") || (typeof errorCallback !== "function"))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if ((typeof serviceDeclaration.serviceName !== "string") ||
+            (typeof serviceDeclaration.serviceTypeId !== "string") ||
+            (typeof serviceDeclaration.providerId !== "string") ||
+            (typeof serviceDeclaration.enabled !== "boolean") ||
+            (typeof serviceDeclaration.settings !== "string") ||
+            (typeof serviceDeclaration.displayName !== "string") ||
+            (typeof serviceDeclaration.icon !== "string") ||
+            (!serviceDeclaration.tags instanceof Array))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        for (count in _data.accountServiceClasses) {
+            if ((_data.accountServiceClasses[count].serviceTypeId === serviceDeclaration.serviceTypeId) &&
+                (_data.accountServiceClasses[count].providerId === serviceDeclaration.providerId) &&
+                (serviceDeclaration.id === undefined)) {
+                errorCallback();
+                return;
+            }
+        }
+        _data.accountServiceClasses.push(serviceDeclaration);
+        if ((_data.accounts.length !== 0) && (serviceDeclaration.accountId !== undefined)) {
+            for (count in _data.accounts) {
+                if (_data.accounts[count].id === serviceDeclaration.accountId) {
+                    _data.accounts[count].services.push(serviceDeclaration);
+                }
+            }
+        }
+        successCallback(serviceDeclaration);
+    }
+};
+
+function _initialize() {
+    var provider = {
+        id : "com.google",
+        displayName : "google",
+        icon : "path/google/pic.png"
+    },
+    type = {
+        id : "tizen.tel",
+        displayName : "tel",
+        icon : "path/type.png",
+        tags : ["call.voice", "call.video", "call.emergency", "call.gsm", "call.cdma", "call.pstn"]
+    },
+    serviceClass = {
+        serviceName : "com.google.gtalk",
+        displayName : "gtalk",
+        icon : "path/google/talk.png",
+        serviceTypeId : "tizen.tel",
+        providerId : "com.google",
+        enabled : true,
+        tags : [],
+        settings : {}
+    };
+
+    _data.accounts = db.retrieveObject(_data.DB_ACCOUNT_KEY) || [];
+    _data.accountServiceClasses.push(serviceClass);
+    _data.accountServiceProviders.push(provider);
+    _data.accountServiceTypes.push(type);
+}
+
+_initialize();
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/poiBackend_openmapquest', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var lbs = require('ripple/platform/tizen/1.0/lbs_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    POIGeometry = require('ripple/platform/tizen/1.0/POIGeometry'),
+    SimpleCoordinates = require('ripple/platform/tizen/1.0/SimpleCoordinates'),
+    _security;
+
+function POIPublic(prop) {
+    /* This is created for public use */
+    var _self, i, copy, attr,  _id = null, _providerName = null;
+    if (prop.id) {
+        _id = prop.id;
+    }
+    if (prop.providerName) {
+        _providerName = prop.providerName;
+    }
+    _self = {
+        name : null,
+        categories : [],
+        address : null,
+        phoneNumbers : [],
+        geometry : null,
+        urls : [],
+        rating : null,
+        tags : null,
+        toGeoJSON : function () {
+            throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
+        }
+    };
+
+    _self.__defineGetter__("id", function () {
+        return _id;
+    });
+
+    _self.__defineGetter__("providerName", function () {
+        return _providerName;
+    });
+
+    if (prop) {
+        if (prop.name) {
+            _self.name = String(prop.name);
+        }
+        if (tizen1_utils.isValidArray(prop.categories)) {
+            _self.categories = [];
+            for (i in prop.categories) {
+                _self.categories.push(String(prop.categories[i]));
+            }
+        }
+        if (prop.address) {
+            if (typeof prop.address === "string") {
+                _self.address = String(prop.address);
+            } else if (Object.prototype.toString.call(prop.address) === "[object Object]") {
+                copy = prop.address.constructor();
+                for (attr in prop.address) {
+                    if (prop.address.hasOwnProperty(attr)) {
+                        copy[attr] = prop.address[attr];
+                    }
+                }
+                _self.address = copy;
+            }
+        }
+        if (tizen1_utils.isValidArray(prop.phoneNumbers)) {
+            _self.phoneNumbers = [];
+            for (i in prop.phoneNumbers) {
+                _self.phoneNumbers.push(String(prop.phoneNumbers[i]));
+            }
+        }
+        if (prop.geometry) {
+            _self.geometry = new POIGeometry(prop.geometry.position, prop.geometry.viewport, prop.geometry.wkt);
+        }
+        if (tizen1_utils.isValidArray(prop.urls)) {
+            _self.urls = [];
+            for (i in prop.urls) {
+                _self.urls.push(String(prop.urls[i]));
+            }
+        }
+        if (typeof prop.rating === "number") {
+            _self.rating = prop.rating;
+        }
+        if (Object.prototype.toString.call(prop.tags) === "[object Object]") {
+            copy = prop.tags.constructor();
+            for (attr in prop.tags) {
+                if (prop.tags.hasOwnProperty(attr)) {
+                    copy[attr] = prop.tags[attr];
+                }
+            }
+            _self.tags = copy;
+        }
+    }
+
+    return _self;
+}
+
+module.exports = function (prop) {
+
+    var _self = new lbs.LocationServiceProvider(prop);
+
+    if (prop.metaData) {
+        _security = prop.metaData;
+    }
+
+    _self.__defineGetter__("supportedFilterTypes", function () {
+        return [];
+    });
+
+    _self.__defineGetter__("supportedPOIFilterAttributes", function () {
+        return [];
+    });
+
+    _self.__defineGetter__("supportedCategories", function () {
+        /* reference: http://wiki.openstreetmap.org/wiki/Map_Features#Amenity */
+        return ["bar", "bbq", "biergarten", "cafe", "drinking_water", "fast_food", "food_court", "ice_cream",
+                "pub", "restaurant", "college", "kindergarten", "library", "school", "university",
+                "bicycle_parking", "bicycle_rental", "bus_station", "car_rental", "car_sharing", "car_wash",
+                "ev_charging", "ferry_terminal", "fuel", "grit_bin", "parking", "parking_entrance",
+                "parking_space", "taxi", "atm", "bank", "bureau_de_change", "baby_hatch", "clinic",
+                "dentist", "doctors", "hospital", "nursing_home", "pharmacy", "social_facility", "veterinary",
+                "arts_centre", "cinema", "community_centre", "fountain", "nightclub", "social_centre",
+                "stripclub", "studio", "swingerclub", "theatre", "bench", "brothel", "clock", "courthouse",
+                "crematorium", "embassy", "fire_station", "grave_yard", "hunting_stand", "marketplace",
+                "place_of_worship", "police", "post_box", "post_office", "prison", "public_building",
+                "recycling", "sauna", "shelter", "shower", "telephone", "toilets", "townhall", "vending_machine",
+                "waste_basket", "waste_disposal", "watering_place"];
+    });
+
+    _self.__defineGetter__("capabilities", function () {
+        /* The set is empty, indicating that this provider supports only 'find' operations */
+        return [];
+    });
+
+    _self.find = function (point, successCallback, errorCallback, options) {
+        /* This provider only supports searching by "GeoRectBounds" due to MapQuest XAPI limitation */
+
+        function _find() {
+            var searchStr, pois = [], isTypeOK = false,
+                id, providerName, name, categories = [], geometry;
+
+            if (Object.prototype.toString.call(point) === "[object Object]") {
+                if (point.southWest && point.northEast) {
+                    if (typeof point.southWest.latitude === "number" &&
+                        typeof point.southWest.longitude === "number" &&
+                        typeof point.northEast.latitude === "number" &&
+                        typeof point.northEast.longitude === "number") {
+                        isTypeOK = true;
+                    }
+                }
+            }
+
+            if (!isTypeOK) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+
+            searchStr = "http://open.mapquestapi.com/xapi/api/0.6/node";
+            if (options && tizen1_utils.isValidArray(options.categories) &&
+                options.categories.length > 0 && typeof options.categories[0] === "string") {
+                /* xapi support single amenity only */
+                searchStr += "[amenity=" + options.categories[0] + "]";
+            }
+            searchStr += "[bbox=" + point.southWest.longitude + "," + point.southWest.latitude + "," +
+                point.northEast.longitude + "," + point.northEast.latitude + "]";
+
+            /* use Open MapQuest online xapi service. (http://open.mapquestapi.com/xapi/) */
+            $.ajax({
+                type: "GET",
+                url: searchStr,
+                dataType: "xml",
+                timeout: 15000, /* 15 secs timeout */
+                success: function (xml) {
+                    providerName = $(xml).find("osm").attr("generator");
+                    $(xml).find("node").each(function () {
+                        var $item = $(this);
+                        categories = [];
+                        id = $item.attr("id");
+                        geometry = new POIGeometry(new SimpleCoordinates($item.attr("lat"), $item.attr("lon")));
+                        $item.find("tag").each(function () {
+                            if ($(this).attr("k") === "name") {
+                                name = $(this).attr("v");
+                            } else if ($(this).attr("k") === "amenity") {
+                                categories.push($(this).attr("v"));
+                            }
+                        });
+                        pois.push(new POIPublic({id: id, providerName: providerName, name: name,
+                                                categories: categories, geometry: geometry}));
+                    });
+                    successCallback(pois);
+                },
+                error: function (obj, msg) {
+                    if (errorCallback) {
+                        if (msg === "timeout") {
+                            setTimeout(function () {
+                                errorCallback(new WebAPIError(errorcode.TIMEOUT_ERR));
+                            }, 1);
+                        } else {
+                            setTimeout(function () {
+                                errorCallback(new WebAPIError(errorcode.NETWORK_ERR));
+                            }, 1);
+                        }
+                    }
+                }
+            });
+        }
+
+        if (!_security.all && !_security.find) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find);
+    };
+
+    _self.update = function (poi, successCallback, errorCallback) {
+        if (!_security.all && !_security.update) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
+    };
+
+    _self.add = function (poi, successCallback, errorCallback) {
+        if (!_security.all && !_security.add) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
+    };
+
+    _self.remove = function (poi, successCallback, errorCallback) {
+        if (!_security.all && !_security.remove) {
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+        }
+
+        throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
+    };
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/application', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    applicationService = require('ripple/platform/tizen/1.0/ApplicationService'),
+    _security = {
+        "http://tizen.org/api/application": [],
+        "http://tizen.org/api/application.launch": ["launch", "launchService"],
+        "http://tizen.org/api/application.kill": ["kill"],
+        "http://tizen.org/api/application.read": [""],
+        all: true
+    },
+    _data = {
+        applications : null,
+        applicationContexts : [],
+        activeApp : null,
+        listeners : {}
+    },
+    _self;
+
+/* applications
+ * [{appId: "org.tizen.apps.alarm", appInfo: {}, appServices: []}]
+ */
+
+/* applicationContexts
+ * [{id: Math.uuid(null, 16), appId: "org.tizen.apps.alarm", parent: null, children: [], service: {}}]
+ */
+
+function _initialize() {
+    event.trigger("appsInit", [_data]);
+}
+
+_initialize();
+
+_self = function () {
+    // private
+    function getHandle() {
+        var handle;
+        do {
+            handle = Math.uuid(10, 10);
+        } while (handle.toString().indexOf('0') === 0);
+        return handle;
+    }
+
+    function sortNumber(a, b) {
+        return b - a;
+    }
+
+    function getChildren(id) {
+        var i, j, k, temp, children = [], index = [];
+
+        for (i in _data.applicationContexts) {
+            if (_data.applicationContexts[i].appId === id) {
+                children = _data.applicationContexts[i].children;
+                index.push(i);
+                break;
+            }
+        }
+        do {
+            temp = [];
+            for (j in children) {
+                for (k in _data.applicationContexts) {
+                    if (_data.applicationContexts[k].appId === children[j]) {
+                        index.push(k);
+                        temp = temp.concat(_data.applicationContexts[k].children);
+                    }
+                }
+            }
+            children = temp;
+        } while (children.length !== 0);
+
+        return index;
+    }
+
+    function clearChildren(id, index) {
+        var i, j, k, temp;
+
+        for (i in _data.applicationContexts) {
+            if ((i !== index) && (_data.applicationContexts[i].children.length !== 0)) {
+                temp = [];
+                for (j in _data.applicationContexts[i].children) {
+                    if (_data.applicationContexts[i].children[j] === id) {
+                        temp.push(j);
+                    }
+                }
+                if (temp.length !== 0) {
+                    temp.sort(sortNumber);
+                    for (k in temp) {
+                        _data.applicationContexts[i].children.splice(temp[k], 1);
+                    }
+                }
+            }
+        }
+    }
+
+    function closeApp(id, successCallback, errorCallback) {
+        var i, children = getChildren(id);
+
+        children.sort(sortNumber);
+
+        for (i in children) {
+            _data.applicationContexts.splice(children[i], 1);
+        }
+        if (successCallback) {
+            successCallback();
+        }
+    }
+
+    // public
+    function launch(id, successCallback, errorCallback, argument) {
+        var i, j, context, isRunning = false;
+
+        if (!_security.all && !_security.launch)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        if (typeof id !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        for (i in _data.applications) {
+            if (_data.applications[i].appId === id) {
+                for (j in _data.applicationContexts) {
+                    if (_data.applicationContexts[j].appId === id) {
+                        isRunning = true;
+                        context = _data.applicationContexts[j];
+                        break;
+                    }
+                }
+                if (!isRunning) {
+                    context = {id : Math.uuid(null, 16), appId : id, parent : "", children : [], service : {}};
+                    _data.applicationContexts.push(context);
+                }
+                _data.activeApp = context;
+                if (successCallback) {
+                    successCallback();
+                }
+                return;
+            }
+        }
+        if (errorCallback) {
+            errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
+        }
+    }
+
+    function kill(contextId, successCallback, errorCallback) {
+        var i, j, appId;
+
+        if (!_security.all && !_security.kill)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        if (typeof contextId !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        for (i in _data.applicationContexts) {
+            if (_data.applicationContexts[i].id === contextId) {
+                appId = _data.applicationContexts[i].appId;
+                j = i;
+            }
+        }
+        if (!appId) {
+            if (errorCallback)
+                errorCallback();
+            return;
+        }
+        closeApp(appId, successCallback, errorCallback);
+    }
+
+    function exit() {
+        if (!_data.activeApp)
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        closeApp(_data.activeApp.appId, null, null);
+        if (_data.applicationContexts.length > 0) {
+            _data.activeApp = _data.applicationContexts[_data.applicationContexts.length - 1];
+        } else {
+            _data.activeApp = null;
+        }
+    }
+
+    function hide() {
+        var i;
+
+        if (!_data.activeApp)
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        if (_data.applicationContexts.length === 1) {
+            _data.activeApp = null;
+            return;
+        }
+        for (i in _data.applicationContexts) {
+            if (_data.applicationContexts[i].appId === _data.activeApp.appId) {
+                if (_data.applicationContexts.length > 0) {
+                    _data.activeApp = _data.applicationContexts[_data.applicationContexts.length - 1];
+                } else {
+                    _data.activeApp = null;
+                }
+                break;
+            }
+        }
+    }
+
+    function launchService(service, id, successCallback, errorCallback, replyCB) {
+        var i, j, k, isRunning = false, appContext, activeApp;
+
+        if (!_security.all && !_security.launch)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        if ((typeof service !== "object") ||
+            (typeof service.operation !== "string") ||
+            (service.uri && (typeof service.uri !== "string")) ||
+            (service.mime && (typeof service.mime !== "string")) ||
+            (!service.data instanceof Array) ||
+            (typeof service.replyResult !== "function") ||
+            (typeof service.replyFailure !== "function"))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (id && (typeof id !== "string"))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        if (replyCB && ((typeof replyCB !== "object") ||
+            (replyCB.onsuccess && (typeof replyCB.onsuccess !== "function")) ||
+            (replyCB.fail && (typeof replyCB.fail !== "function"))))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (id) {
+            for (i in _data.applications) {
+                if (_data.applications[i].appId === id) {
+                    for (j in _data.applicationContexts) {
+                        if (_data.applicationContexts[j].appId === _data.activeApp.appId) {
+                            _data.applicationContexts[j].children.push(id);
+                            clearChildren(id, j);
+                        }
+                        if (_data.applicationContexts[j].appId === id) {
+                            _data.applicationContexts[j].service = service;
+                            _data.applicationContexts[j].parent = _data.activeApp.appId;
+                            activeApp = _data.applicationContexts[j];
+                            isRunning = true;
+                        }
+                    }
+                    if (isRunning) {
+                        _data.activeApp = activeApp;
+                        return;
+                    }
+                    appContext = {id : Math.uuid(null, 16), appId : id, parent : _data.activeApp.appId, children : [], service : service};
+                    _data.applicationContexts.push(appContext);
+                    _data.activeApp = appContext;
+                    service.replyResult(service.data);
+                    if (successCallback) {
+                        successCallback();
+                    }
+                    if (replyCB) {
+                        replyCB.onsuccess(service.data);
+                    }
+                    return;
+                }
+            }
+        } else {
+            for (i in _data.applications) {
+                for (j in _data.applications[i].appServices) {
+                    if (service.operation === _data.applications[i].appServices[j].operation) {
+                        for (k in _data.applicationContexts) {
+                            if (_data.applicationContexts[k].appId === _data.activeApp.appId) {
+                                _data.applicationContexts[k].children.push(_data.applications[i].appId);
+                                clearChildren(id, k);
+                            }
+                            if (_data.applicationContexts[k].appId === _data.applications[i].appId) {
+                                activeApp = _data.applicationContexts[k];
+                                _data.applicationContexts[k].service = service;
+                                _data.applicationContexts[k].parent = _data.activeApp.appId;
+                                isRunning = true;
+                            }
+                        }
+                        if (isRunning) {
+                            _data.activeApp = activeApp;
+                            return;
+                        }
+                        appContext = {id : Math.uuid(null, 16), appId : _data.applications[i].appId, parent : _data.activeApp.id, children : [], service : service};
+                        _data.applicationContexts.push(appContext);
+                        _data.activeApp = appContext;
+                        service.replyResult(service.data);
+                        if (successCallback) {
+                            successCallback();
+                        }
+                        if (replyCB) {
+                            replyCB.onsuccess(service.data);
+                        }
+                        return;
+                    }
+                }
+            }
+        }
+        if (replyCB) {
+            replyCB.onfail();
+        }
+        if (errorCallback) {
+            errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
+        }
+    }
+
+    function getAppService() {
+        if (!_data.activeApp)
+            throw new WebAPIError(errorcode.UNKNOWN_ERR);
+
+        return _data.activeApp.service;
+    }
+
+    function getAppsContext(successCallback, errorCallback) {
+        var i, context, appsContext = [];
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        for (i in _data.applicationContexts) {
+            context = {id : _data.applicationContexts[i].id, appId : _data.applicationContexts[i].appId};
+            appsContext.push(context);
+        }
+        successCallback(appsContext);
+    }
+
+    function getAppContext(id) {
+        var i, contextId, appContext;
+
+        if (id && (typeof id !== "string"))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        contextId = id || _data.activeApp.appId;
+        for (i in _data.applicationContexts) {
+            if (_data.applicationContexts[i].id === contextId) {
+                appContext = {
+                    id : _data.applicationContexts[i].id,
+                    appId : _data.applicationContexts[i].appId
+                };
+                break;
+            }
+        }
+
+        if (!appContext)
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        return appContext;
+    }
+
+    function getAppsInfo(successCallback, errorCallback) {
+        var i, appsInfo = [];
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        for (i in _data.applications) {
+            appsInfo.push(_data.applications[i].appInfo);
+        }
+        successCallback(appsInfo);
+    }
+
+    function getAppInfo(id) {
+        var i, appId, appInfo;
+
+        if (typeof id !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        appId = id || _data.activeApp.appId;
+
+        for (i in _data.applications) {
+            if (_data.applications[i].appId === appId) {
+                appInfo = _data.applications[i].appInfo;
+                break;
+            }
+        }
+
+        if (!appInfo)
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        return appInfo;
+    }
+
+    function addAppInfoEventListener(eventCallback, errorCallback) {
+        var handle;
+
+        if (!eventCallback ||
+            (errorCallback && (typeof errorCallback !== "function")) ||
+            (eventCallback && (typeof eventCallback !== "object")) ||
+            (eventCallback.oninstalled && (typeof eventCallback.oninstalled !== "function")) ||
+            (eventCallback.onupdated && (typeof eventCallback.onupdated !== "function")) ||
+            (eventCallback.onuninstalled && (typeof eventCallback.onuninstalled !== "function")))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        handle = getHandle();
+        _data.listeners[handle] = eventCallback;
+
+        return handle;
+    }
+
+    function removeAppInfoEventListener(listenerID) {
+        if (typeof listenerID !== "number")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (!_data.listeners[listenerID])
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        delete _data.listeners[listenerID];
+    }
+
+    function handleSubFeatures(subFeatures) {
+        for (var subFeature in subFeatures) {
+            if (_security[subFeature].length === 0) {
+                _security.all = true;
+                return;
+            }
+            _security.all = false;
+            utils.forEach(_security[subFeature], function (method) {
+                _security[method] = true;
+            });
+        }
+    }
+
+    var application = {
+        launch : launch,
+        kill : kill,
+        exit : exit,
+        hide : hide,
+        launchService : launchService,
+        getAppService : getAppService,
+        getAppsContext : getAppsContext,
+        getAppContext : getAppContext,
+        getAppsInfo : getAppsInfo,
+        getAppInfo : getAppInfo,
+        addAppInfoEventListener : addAppInfoEventListener,
+        removeAppInfoEventListener : removeAppInfoEventListener,
+        handleSubFeatures : handleSubFeatures
+    };
+
+    return application;
+};
+
+event.on("programChanged", function (status, param) {
+    var callback, id;
+
+    switch (status) {
+    case "installed":
+    case "updated":
+    case "uninstalled":
+        callback = "on" + status;
+        break;
+
+    default:
+        return;
+    }
+
+    for (id in _data.listeners) {
+        _data.listeners[id][callback](param);
+    }
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/mediacontent', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    PendingObject = require('ripple/platform/tizen/1.0/pendingObject'),
+    PendingOperation = require('ripple/platform/tizen/1.0/pendingoperation'),
+    MediaSource,
+    _data = {
+        DB_MEDIACONTENT_KEY: "tizen1-db-mediacontent",
+        mediaSource: null,
+        folders: [],
+        items: []
+    },
+    _self;
+
+function _defaultMediaContent() {
+    var video1 = {
+        id: Math.uuid(null, 16),
+        editableAttibutes: ["title", "description", "rating", "playedTime", "artists", "album"],
+        title: "olympic",
+        type: "VIDEO",
+        mimeType: "video/x-msvideo",
+        duration: 1245,
+        width: 480,
+        height: 240,
+        itemURI : "videos/olympic.avi",
+        rating: 4,
+        playedTime: 1230,
+        description: "Olympic Games",
+        createdDate: new Date(),
+        artists: ["olympic"],
+        album: "olympic"
+    },
+    video2 = {
+        id: Math.uuid(null, 16),
+        editableAttibutes: ["title", "description", "rating", "playCount"],
+        title: "galaxy",
+        type: "VIDEO",
+        duration: 156,
+        width: 220,
+        height: 180,
+        itemURI : "videos/galaxy.rmvb",
+        description: "Universe Spectacle",
+        rating: 5,
+        playCount: 2,
+        createdDate: new Date(),
+        modifiedDate: new Date()
+    },
+    image1 = {
+        id: Math.uuid(null, 16),
+        editableAttibutes: ["title", "orientation", "description", "rating"],
+        title: "greatwall",
+        type: "IMAGE",
+        width: 480,
+        height: 240,
+        size: 1024,
+        description: "GREATEWALL",
+        itemURI: "images/greatwall.jpg",
+        createdDate: new Date(),
+        rating: 1,
+        orientation: "NORMAL"
+    },
+    image2 = {
+        id: Math.uuid(null, 16),
+        editableAttibutes: ["title", "orientation", "description", "rating"],
+        title: "seagull",
+        type: "IMAGE",
+        width: 480,
+        height: 240,
+        itemURI: "images/seagull.gif",
+        createdDate: new Date(),
+        description: "SEAGULL",
+        rating: 2,
+        orientation: "ROTATE_180"
+    },
+    audio1 = {
+        id: Math.uuid(null, 16),
+        editableAttibutes: ["title", "album", "genres", "artists", "composers"],
+        title: "rock",
+        type: "AUDIO",
+        itemURI: "music/rock.mp3",
+        createdDate: new Date(),
+        album: "rock",
+        genres: ["R&B"],
+        artists: ["eminem"],
+        composers: ["eminem"],
+        copyright: "Copyright Rocky",
+        bitrate: 128
+    },
+    audio2 = {
+        id: Math.uuid(null, 16),
+        editableAttibutes: ["title", "album", "genres", "artists", "composers"],
+        title: "jazz",
+        type: "AUDIO",
+        itemURI: "music/jazz.acc",
+        createdDate: new Date(),
+        album: "jazz",
+        genres: ["jazz"],
+        artists: ["jackson"],
+        composers: ["johnson"],
+        copyright: "Copyright Rocky",
+        bitrate: 128
+    },
+    videoFolder = {
+        id: Math.uuid(null, 16),
+        folderURI: "videos/",
+        title: "videos",
+        storageType: "INTERNAL",
+        modifiedDate: new Date(),
+    },
+    audioFolder = {
+        id: Math.uuid(null, 16),
+        folderURI: "music/",
+        title: "music",
+        storageType: "EXTERNAL",
+        modifiedDate: new Date(),
+    },
+    imageFolder = {
+        id: Math.uuid(null, 16),
+        folderURI: "images/",
+        title: "images",
+        storageType: "EXTERNAL",
+        modifiedDate: new Date(),
+    },
+    mc = {
+        folders: [videoFolder, audioFolder, imageFolder],
+        items: [video1, video2, image1, image2, audio1, audio2]
+    };
+
+    db.saveObject(_data.DB_MEDIACONTENT_KEY, mc);
+
+    return mc;
+}
+
+function _initialize() {
+    var mc = db.retrieveObject(_data.DB_MEDIACONTENT_KEY) || _defaultMediaContent();
+
+    _data.mediaSource = new MediaSource();
+    _data.items       = mc.items;
+    _data.folders     = mc.folders;
+}
+
+_self = {
+    getLocalMediaSource: function () {
+        return _data.mediaSource;
+    }
+};
+
+MediaSource = function () {
+    // private
+    function find(successCallback, errorCallback, src, filter, sortMode, count, offset) {
+        var items;
+
+        if (src.length === 0) {
+            if (errorCallback) {
+                setTimeout(function () {
+                    errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                }, 1);
+            }
+            return;
+        }
+
+        items = tizen1_utils.query(src, filter, sortMode, count, offset);
+        successCallback(utils.copy(items));
+    }
+
+    function update(items, successCallback, errorCallback) {
+        var i, j, mc, count = 0, isFound = false, matched = [];
+
+        if (tizen1_utils.isValidArray(items)) {
+            for (i in items) {
+                for (j in _data.items) {
+                    if (items[i].id === _data.items[j].id) {
+                        ++count;
+                        matched.push(j);
+                        break;
+                    }
+                }
+            }
+
+            if (count === items.length) {
+                for (i in matched) {
+                    _data.items[matched[i]] = utils.copy(items[i]);
+                }
+                isFound = true;
+            }
+        } else {
+            for (i in _data.items) {
+                if (_data.items[i].id === items.id) {
+                    _data.items[i] = utils.copy(items);
+                    isFound = true;
+                    break;
+                }
+            }
+        }
+
+        if (isFound) {
+            mc = {folders: _data.folders, items: _data.items};
+            db.saveObject(_data.DB_MEDIACONTENT_KEY, mc);
+            if (successCallback) {
+                successCallback();
+            }
+        } else if (errorCallback) {
+            setTimeout(function () {
+                errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
+            }, 1);
+        }
+    }
+
+    // public
+    function updateItem(item) {
+        update(item);
+    }
+
+    function updateItemsBatch(items, successCallback, errorCallback) {
+        function _updateItemsBatch() {
+            var pendingObj;
+
+            pendingObj = new PendingObject();
+            pendingObj.pendingID = setTimeout(function () {
+                pendingObj.setCancelFlag(false);
+                update(items, successCallback, errorCallback);
+            }, 1);
+
+            return new PendingOperation(pendingObj);
+        }
+        return tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "mediacontent:updateItemsBatch", _updateItemsBatch);
+    }
+
+    function getFolders(successCallback, errorCallback) {
+        function _getFolders() {
+            if (_data.folders.length === 0) {
+                if (errorCallback) {
+                    setTimeout(function () {
+                        errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                    }, 1);
+                }
+                return;
+            }
+
+            successCallback(_data.folders);
+        }
+        return tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "mediacontent:getFolders", _getFolders);
+    }
+
+    function findItems(successCallback, errorCallback, folderId, filter, sortMode, count, offset) {
+        function _findItems() {
+            var src = [], i, folderURI, parentURI, _re;
+            if (folderId) {
+                for (i in _data.folders) {
+                    if (_data.folders[i].id === folderId) {
+                        folderURI = _data.folders[i].folderURI;
+                        break;
+                    }
+                }
+
+                if (!folderURI) {
+                    if (errorCallback) {
+                        setTimeout(function () {
+                            errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                        }, 1);
+                    }
+                    return;
+                }
+
+                _re = new RegExp("^" + folderURI, "i");
+
+                for (i in _data.items) {
+                    if(_data.items[i].itemURI.search(_re) !== -1) {
+                        src.push(_data.items[i]);
+                    }
+                }
+            } else {
+                src = _data.items;
+            }
+            find(successCallback, errorCallback, src, filter, sortMode, count, offset);
+        }
+
+        return tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "mediacontent:findItems", _findItems);
+    }
+
+    function browseFolder(id, successCallback, errorCallback, filter, sortMode, count, offset) {
+        function _browseFolder() {
+            var src = [], i, j, k, folderURI, parentURI;
+            if (_data.folders.length === 0) {
+                if (errorCallback) {
+                    setTimeout(function () {
+                        errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                    }, 1);
+                }
+                return;
+            }
+
+            for (i in _data.folders) {
+                if (_data.folders[i].id === id) {
+                    folderURI = _data.folders[i].folderURI;
+                    break;
+                }
+                if (!folderURI) {
+                    if (errorCallback) {
+                        setTimeout(function () {
+                            errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                        }, 1);
+                    }
+                    return;
+                }
+            }
+
+            for (i in _data.items) {
+                parentURI = _data.items[i].itemURI;
+                parentURI = parentURI.slice(0, parentURI.lastIndexOf('/'));
+                if (parentURI === folderURI) {
+                    src.push(_data.items[i]);
+                }
+            }
+
+            if (src.length === 0) {
+                if (errorCallback) {
+                    setTimeout(function () {
+                        errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+                    }, 1);
+                }
+                return;
+            }
+
+            find(successCallback, errorCallback, src, filter, sortMode, count, offset);
+        }
+        return tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "mediacontent:browseFolder", _browseFolder);
+    }
+
+    this.updateItem       = updateItem;
+    this.updateItemsBatch = updateItemsBatch;
+    this.getFolders       = getFolders;
+    this.findItems        = findItems;
+    this.browseFolder     = browseFolder;
+};
+
+_initialize();
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/DeviceOrientationEvent', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var Event = require('ripple/platform/tizen/1.0/EventBase');
+
+module.exports = function () {
+    var _self = {
+            alpha: null,
+            beta: null,
+            gamma: null,
+            absolute: false,
+        };
+
+    Event.call(this);
+
+    this.__defineGetter__("alpha", function () {
+        return _self.alpha;
+    });
+
+    this.__defineGetter__("beta", function () {
+        return _self.beta;
+    });
+
+    this.__defineGetter__("gamma", function () {
+        return _self.gamma;
+    });
+
+    this.__defineGetter__("absolute", function () {
+        return _self.absolute;
+    });
+
+    this.initDeviceOrientationEvent = function (orientationType, orientationBubbles, orientationCancelable,
+                                               alphaData, betaData, gammaData, isAbsolute) {
+        this.initEvent(orientationType, orientationBubbles, orientationCancelable);
+
+        _self.alpha    = alphaData;
+        _self.beta     = betaData;
+        _self.gamma    = gammaData;
+        _self.absolute = isAbsolute;
+    };
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/route', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    SimpleCoordinates = require('ripple/platform/tizen/1.0/SimpleCoordinates'),
+    ProviderNominatim = require('ripple/platform/tizen/1.0/routeBackend_navigation'), // navigation route service
+    _getProviders,
+    _providers,
+    _self;
+
+function _initialize() {
+    _providers = [new ProviderNominatim({name : "Nominatim", connectivity : "ONLINE"})];
+}
+
+_initialize();
+
+_self = {
+    getDefaultProvider : function () {
+        if (arguments.length !== 0) {
+            throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
+        }
+        return _providers[0];
+    },
+    getProviders : function () {
+        if (arguments.length !== 0) {
+            throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
+        }
+        return _providers;
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/POIBase', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    POIGeometry = require('ripple/platform/tizen/1.0/POIGeometry'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError');
+
+
+module.exports = function (prop) {
+    var _self, i, copy, attr;
+    _self = {
+        name : null,
+        categories : [],
+        address : null,
+        phoneNumbers : [],
+        geometry : null,
+        urls : [],
+        rating : null,
+        tags : null,
+        toGeoJSON : function () {
+            throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
+        }
+    };
+
+    _self.__defineGetter__("id", function () {
+        return null;
+    });
+
+    _self.__defineGetter__("providerName", function () {
+        return null;
+    });
+
+    if (prop) {
+        if (prop.name) {
+            _self.name = String(prop.name);
+        }
+        if (tizen1_utils.isValidArray(prop.categories)) {
+            _self.categories = [];
+            for (i in prop.categories) {
+                _self.categories.push(String(prop.categories[i]));
+            }
+        }
+        if (prop.address) {
+            if (typeof prop.address === "string") {
+                _self.address = String(prop.address);
+            } else if (Object.prototype.toString.call(prop.address) === "[object Object]") {
+                copy = prop.address.constructor();
+                for (attr in prop.address) {
+                    if (prop.address.hasOwnProperty(attr)) {
+                        copy[attr] = prop.address[attr];
+                    }
+                }
+                _self.address = copy;
+            }
+        }
+        if (tizen1_utils.isValidArray(prop.phoneNumbers)) {
+            _self.phoneNumbers = [];
+            for (i in prop.phoneNumbers) {
+                _self.phoneNumbers.push(String(prop.phoneNumbers[i]));
+            }
+        }
+        if (prop.geometry) {
+            _self.geometry = new POIGeometry(prop.geometry.position, prop.geometry.viewport, prop.geometry.wkt);
+        }
+        if (tizen1_utils.isValidArray(prop.urls)) {
+            _self.urls = [];
+            for (i in prop.urls) {
+                _self.urls.push(String(prop.urls[i]));
+            }
+        }
+        if (typeof prop.rating === "number") {
+            _self.rating = prop.rating;
+        }
+        if (Object.prototype.toString.call(prop.tags) === "[object Object]") {
+            copy = prop.tags.constructor();
+            for (attr in prop.tags) {
+                if (prop.tags.hasOwnProperty(attr)) {
+                    copy[attr] = prop.tags[attr];
+                }
+            }
+            _self.tags = copy;
+        }
+    }
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/lbs_utils', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    _self;
+
+function CoordinateProperties(prop) {
+    var _self;
+    _self = {
+        latitude : prop.latitude || 0,
+        longitude : prop.longitude || 0,
+        altitude : prop.altitude || 0,
+        accuracy : prop.accuracy || 0,
+        altitudeAccuracy : prop.altitudeAccuracy || 0,
+        heading : prop.heading || 0,
+        speed : prop.speed || 0
+    };
+    return _self;
+}
+
+function _checkAddressProperties(p, dst) {
+    if (p.country !== null && p.country !== undefined)
+        dst.country = String(p.country);
+    if (p.region !== null && p.region !== undefined)
+        dst.region = String(p.region);
+    if (p.county !== null && p.county !== undefined)
+        dst.county = String(p.county);
+    if (p.city !== null && p.city !== undefined)
+        dst.city = String(p.city);
+    if (p.street !== null && p.street !== undefined)
+        dst.street = String(p.street);
+    if (p.streetNumber !== null && p.streetNumber !== undefined)
+        dst.streetNumber = String(p.streetNumber);
+    if (p.premises !== null && p.premises !== undefined)
+        dst.premises = String(p.premises);
+    if (p.additionalInformation !== null && 
+        p.additionalInformation !== undefined)
+        dst.additionalInformation = String(p.additionalInformation);
+    if (p.postalCode !== null && p.postalCode !== undefined)
+        dst.postalCode = String(p.postalCode);
+}
+
+function AddressProperties(prop) {
+    var _self;
+    _self = {
+        country : null,
+        region : null,
+        county : null,
+        city : null,
+        street : null,
+        streetNumber : null,
+        premises : null,
+        additionalInformation : null,
+        postalCode : null
+    };
+    if (prop) {
+        if (_checkAddressProperties(prop, _self) === false)
+            return undefined;
+    }
+    return _self;
+}
+
+_self = {
+    LocationServiceProvider : function (prop) {
+        var _self;
+        _self = {
+            name : "",
+            metaData : Object,
+            attribution : "",
+            supportedOptions : [],
+            setOptions : function (options, successCB, errorCB) {},
+            connectivity : "" // "ONLINE" "OFFLINE" "HYBRID"
+        };
+
+        if (prop.name !== null && prop.name !== undefined)
+            _self.name = String(prop.name); 
+        if (prop.metaData !== null && prop.metaData !== undefined)
+            _self.metaData = prop.metaData;
+
+        if (prop.attribution !== null && prop.attribution !== undefined)
+            _self.attribution = String(prop.attribution);
+
+        if (prop.supportedOptions !== null && prop.supportedOptions !== undefined)
+            _self.supportedOptions = [prop.supportedOptions];
+
+        if (prop.setOptions !== null && prop.setOptions !== undefined)
+            _self.setOptions = prop.setOptions;
+
+        if (prop.connectivity !== null && prop.connectivity !== undefined)
+            _self.connectivity = String(prop.connectivity);
+
+        return _self;
+    },
+
+    GeoCoordinates : function (prop) {
+        var _self = new CoordinateProperties(prop);
+        if (tizen1_utils.isEmptyObject(_self)) {
+            return undefined;
+        }
+
+        return _self;
+    },
+    
+    StructuredAddress : function (prop) {
+        var _self;
+        _self = new AddressProperties(prop);
+        if (tizen1_utils.isEmptyObject(_self)) {
+            return undefined;
+        }
+
+        return _self;
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/geoBackend_nominatim', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var lbs = require('ripple/platform/tizen/1.0/lbs_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    GeocodeResult = require('ripple/platform/tizen/1.0/GeocodeResult');
+
+function _concatAddrString(addr) {
+    var ret = "", i, pieces;
+    if (typeof addr === "string") {
+        pieces = addr.split(" ");
+        for (i = 0; i < pieces.length; i++) {
+            ret = ret + pieces[i] + "+";
+        }
+    } else if (typeof addr === "object") {
+        if (addr.premises !== null && addr.premises !== undefined) {
+            ret = ret + addr.premises + "+";
+        }
+        if (addr.streetNumber !== null && addr.streetNumber !== undefined) {
+            ret = ret + addr.streetNumber + "+";
+        }
+        if (addr.street !== null && addr.street !== undefined) {
+            ret = ret + addr.street + "+";
+        }
+        if (addr.city !== null && addr.city !== undefined) {
+            ret = ret + addr.city + "+";
+        }
+        if (addr.county !== null && addr.county !== undefined) {
+            ret = ret + addr.county + "+";
+        }
+        if (addr.region !== null && addr.region !== undefined) {
+            ret = ret + addr.region + "+";
+        }
+        if (addr.postalCode !== null && addr.postalCode !== undefined) {
+            ret = ret + addr.postalCode + "+";
+        }
+        if (addr.country !== null && addr.country !== undefined) {
+            ret = ret + addr.country + "+";
+        }
+    } else {
+        return undefined;
+    }
+    ret = ret.slice(0, -1);
+    return ret;
+}
+
+module.exports = function (prop) {
+    var _self = new lbs.LocationServiceProvider(prop);
+    
+    _self.geocode = function (address, successCB, errorCB, options) {
+        function _geocode() {
+            var i, searchStr, coordinates = [], result;
+
+            searchStr = _concatAddrString(address);
+            if (searchStr === undefined) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+            searchStr = "http://nominatim.openstreetmap.org/search?q=" + searchStr + "&format=json&polygon=1&addressdetails=1";
+
+            /* use nominatim online geo service. (http://nominatim.openstreetmap.org) */
+            $.getJSON(searchStr, function (data) {
+                for (i = 0; i < data.length; i++) {
+                    result = new GeocodeResult(parseFloat(data[i].lat), parseFloat(data[i].lon));
+                    coordinates.push(result);
+                }
+                successCB(coordinates);
+            }).error(function () {
+                if (errorCB) {
+                    setTimeout(function () {
+                        errorCB(new WebAPIError(errorcode.NETWORK_ERR));
+                    }, 1);
+                }
+            });
+        }
+
+        tizen1_utils.validateTypeMismatch(successCB, errorCB, "geocode", _geocode); 
+    };
+
+    _self.reverseGeocode = function (coordinates, successCB, errorCB, options) {
+        function _reverseGeocode() {
+            var searchStr = "";
+            if (typeof coordinates !== "object" ||
+                typeof coordinates.latitude !== "number" ||
+                typeof coordinates.longitude !== "number") {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+            searchStr = "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
+                        coordinates.latitude + "&lon=" + coordinates.longitude + "&zoom=18&addressdetails=1";
+
+            /* use nominatim online geo service. (http://nominatim.openstreetmap.org) */
+            $.getJSON(searchStr, function (data) {
+                var addr;
+
+                if (options && options.resultType === "STRUCTURED") {
+                    addr = new lbs.StructuredAddress({
+                        country : data.address.country,
+                        region : data.address.state,
+                        county : data.address.county,
+                        city : data.address.city,
+                        street : data.address.road,
+                        streetNumber : data.address.streetNumber,
+                        postalCode : data.address.postcode
+                    });
+                } else {
+                    addr = data.display_name;
+                }
+                successCB([addr]);
+            }).error(function () {
+                if (errorCB) {
+                    setTimeout(function () {
+                        errorCB(new WebAPIError(errorcode.NETWORK_ERR));
+                    }, 1);
+                }
+            });
+        }
+
+        tizen1_utils.validateTypeMismatch(successCB, errorCB, "reverseGeocode", _reverseGeocode);
+    };
+
+    return _self;
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/touchEvent', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var emulatorBridge = require('ripple/emulatorBridge'),
+    event = require('ripple/event'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    Touch,
+    TouchList,
+    TouchEvent,
+    _touchCanvasElements = [],
+    _dataEnlargeRatio = 4,
+    _self;
+
+function _isValidTouch(touches) {
+    var touche, _touches = [], i;
+    if (!touches) {
+        return false;
+    }
+    if (!tizen1_utils.isValidArray(touches)) {
+        _touches = [touches];
+    }
+
+    for (i = 0; i < _touches.length; i++) {
+        touche = _touches[i];
+        if ((touche !== undefined) &&
+            ((typeof touche !== "object") ||
+            (typeof touche.target !== "object") ||
+            (touche.identifier !== undefined) && (typeof touche.identifier !== "number") ||
+            (touche.screenX !== undefined) && (typeof touche.screenX !== "number") ||
+            (touche.screenY !== undefined) && (typeof touche.screenY !== "number") ||
+            (touche.clientX !== undefined) && (typeof touche.clientX !== "number") ||
+            (touche.clientY !== undefined) && (typeof touche.clientY !== "number") ||
+            (touche.pageX !== undefined) && (typeof touche.pageX !== "number") ||
+            (touche.pageY !== undefined) && (typeof touche.pageY !== "number")))
+            return false;
+    }
+    return true;
+}
+
+function _dispatchAllEvents(event) {
+    _touchCanvasElements.forEach(function (value) {
+        if (value !== undefined) {
+            value.dispatchEvent(event);
+        }
+    });
+}
+
+function _touchMove(event) {
+    var data = event.data,
+        touches = [],
+        removedTouches = [],
+        touchList,
+        simulatedEvent,
+        dataId,
+        ids = [],
+        intervalId,
+        currentIndex,
+        item = {};
+
+    if (_touchCanvasElements.length === 0)
+        return;
+
+    for (dataId in data) {
+        if (!data[dataId].length || data[dataId].length === 0)
+            return;
+
+        ids.push(dataId);
+        item = data[dataId][0];
+        touches.push(new Touch(item.target, dataId, item.pageX * _dataEnlargeRatio, item.pageY * _dataEnlargeRatio, item.screenX * _dataEnlargeRatio,
+                               item.screenY * _dataEnlargeRatio, item.offsetX * _dataEnlargeRatio, item.offsetY * _dataEnlargeRatio));
+    }
+
+    // touch start
+    touchList = new TouchList(touches);
+    simulatedEvent = new TouchEvent("touchstart", true, true, touchList, touchList, touchList, event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
+    _dispatchAllEvents(simulatedEvent);
+    currentIndex = 0;
+
+    // touch move and touch end
+    intervalId = setInterval(function () {
+        touches = [];
+        removedTouches = [];
+
+        ids.forEach(function (id) {
+            var points = data[id],
+                touchItem, removedItem;
+
+            if (currentIndex < points.length) {
+                touchItem = points[currentIndex];
+            } else {
+                removedItem = points[points.length - 1];
+            }
+
+            if (touchItem)
+                touches.push(new Touch(touchItem.target, id, touchItem.pageX * _dataEnlargeRatio, touchItem.pageY * _dataEnlargeRatio, touchItem.screenX * _dataEnlargeRatio,
+                                       touchItem.screenY * _dataEnlargeRatio, touchItem.offsetX * _dataEnlargeRatio, touchItem.offsetY * _dataEnlargeRatio));
+            if (removedItem)
+                removedTouches.push(new Touch(removedItem.target, id, removedItem.pageX * _dataEnlargeRatio, removedItem.pageY * _dataEnlargeRatio, removedItem.screenX * _dataEnlargeRatio,
+                                    removedItem.screenY * _dataEnlargeRatio, removedItem.offsetX * _dataEnlargeRatio, removedItem.offsetY * _dataEnlargeRatio));
+        });
+
+        if (touches.length > 0) {
+            simulatedEvent = new TouchEvent("touchmove", true, true, new TouchList(touches), new TouchList(touches), new TouchList(touches),
+                event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
+            _dispatchAllEvents(simulatedEvent);
+        } else {
+            clearInterval(intervalId);
+        }
+
+        if (removedTouches.length > 0) {
+            simulatedEvent = new TouchEvent("touchend", true, true, new TouchList(removedTouches), new TouchList(removedTouches), new TouchList(removedTouches),
+                event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
+            _dispatchAllEvents(simulatedEvent);
+        }
+        currentIndex++;
+    }, 50);
+}
+
+function _touchCancel(event) {
+    var mousedownEvent = event.touchEvent,
+        simulatedEvent;
+
+    simulatedEvent = new TouchEvent("touchcancel", true, true, new TouchList([]), new TouchList([]), new TouchList([]),
+        event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
+    _dispatchAllEvents(simulatedEvent);
+}
+
+function _initialize() {
+    event.on("touchCancel", _touchCancel);
+    event.on("touchEvent", _touchMove);
+}
+
+Touch = function (target, identifier, pageX, pageY, screenX, screenY, clientX, clientY) {
+    var _identifier = Number(identifier) || 0,
+        _screenX = Number(screenX) || 0,
+        _screenY = Number(screenY) || 0,
+        _clientX = Number(clientX) || 0,
+        _clientY = Number(clientY) || 0,
+        _pageX = Number(pageX) || 0,
+        _pageY = Number(pageY) || 0;
+
+    this.__defineGetter__("identifier", function () {
+        return _identifier;
+    });
+    this.__defineGetter__("target", function () {
+        return target;
+    });
+    this.__defineGetter__("screenX", function () {
+        return _screenX;
+    });
+    this.__defineGetter__("screenY", function () {
+        return _screenY;
+    });
+    this.__defineGetter__("clientX", function () {
+        return _clientX;
+    });
+    this.__defineGetter__("clientY", function () {
+        return _clientY;
+    });
+    this.__defineGetter__("pageX", function () {
+        return _pageX;
+    });
+    this.__defineGetter__("pageY", function () {
+        return _pageY;
+    });
+};
+
+TouchList = function (touches) {
+    var _touches = _isValidTouch(touches) ? tizen1_utils.copy(touches) : [],
+        i, _self;
+
+    _self = {
+        item : function (index) {
+            if (typeof index !== "number") {
+                return null;
+            }
+            if (index.toString().indexOf(".") !== -1) {
+                return null;
+            }
+            if (/^\\d+$/.test(index) || index >= _touches.length) {
+                return null;
+            }
+            if (!_touches) {
+                return null;
+            }
+            return _touches[index];
+        },
+
+        identifiedTouch : function (identifier) {
+            if (typeof identifier !== "number") {
+                return null;
+            }
+            if (!_touches) {
+                return null;
+            }
+            for (var i in _touches) {
+                if (_touches[i].identifier === identifier) {
+                    return _touches[i];
+                }
+            }
+            return null;
+        }
+    };
+
+    for (i = 0; i < _touches.length; i++) {
+        _self.__defineGetter__(i, (function (index) {
+            return function () {
+                return _touches[index];
+            };
+        }(i)));
+    }
+
+    _self.__defineGetter__("length", function () {
+        return _touches.length;
+    });
+
+    return _self;
+};
+
+TouchEvent = function (type, canBubble, cancelable, touches, targetTouches, changedTouches, altKey, metaKey, ctrlKey, shiftKey) {
+    var touchEvent = emulatorBridge.document().createEvent("UIEvents");
+    touchEvent.initUIEvent(type, canBubble, cancelable, emulatorBridge.window(), 1);
+
+    touchEvent.__defineGetter__("touches", function () {
+        return touches;
+    });
+    touchEvent.__defineGetter__("targetTouches", function () {
+        return targetTouches;
+    });
+    touchEvent.__defineGetter__("changedTouches", function () {
+        return changedTouches;
+    });
+    touchEvent.__defineGetter__("altKey", function () {
+        return altKey;
+    });
+    touchEvent.__defineGetter__("metaKey", function () {
+        return metaKey;
+    });
+    touchEvent.__defineGetter__("ctrlKey", function () {
+        return ctrlKey;
+    });
+    touchEvent.__defineGetter__("shiftKey", function () {
+        return shiftKey;
+    });
+    return touchEvent;
+};
+
+_self = {
+    mask: function (frame) {
+        frame.contentWindow.addEventListener("DOMContentLoaded", function () {
+            var widgetDocument = frame.contentDocument,
+                getElementByIdOri = widgetDocument.getElementById;
+
+            widgetDocument.getElementById = function () {
+                var element, addEventListenerOri;
+
+                element = getElementByIdOri.apply(widgetDocument, Array.prototype.slice.call(arguments));
+
+                if (element) {
+                    addEventListenerOri = element.addEventListener;
+                    element.addEventListener = function (event, callback, useCapture) {
+                        if (event === "touchstart") {
+                            _touchCanvasElements.push(element);
+                        }
+                        addEventListenerOri.apply(element, arguments);
+                    };
+                }
+                return element;
+            };
+
+            widgetDocument.createTouch = function (view, target, identifier, pageX, pageY, screenX, screenY) {
+                return new Touch(view, target, identifier, pageX, pageY, screenX, screenY);
+            };
+
+            widgetDocument.createTouchList = function (pattern) {
+                if (arguments.length !== 1) {
+                    return null;
+                }
+                return new TouchList(pattern);
+            };
+        });
+    }
+};
+
+_initialize();
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/CalendarAttendee', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (attendeeInitDict) {
+    var _self;
+
+    if (attendeeInitDict) {
+        _self.uri          = (attendeeInitDict.uri) ? attendeeInitDict.uri : "";
+        _self.name         = (attendeeInitDict.name) ? attendeeInitDict.name : "";
+        _self.role         = (attendeeInitDict.role) ? attendeeInitDict.role : "";
+        _self.status       = (attendeeInitDict.status) ? attendeeInitDict.status : "";
+        _self.RSVP         = (attendeeInitDict.RSVP) ? attendeeInitDict.RSVP : "";
+        _self.type         = (attendeeInitDict.type) ? attendeeInitDict.type : "";
+        _self.group        = (attendeeInitDict.group) ? attendeeInitDict.group : "";
+        _self.delegatorURI = (attendeeInitDict.delegatorURI) ? attendeeInitDict.delegatorURI : "";
+        _self.delegateURI  = (attendeeInitDict.delegateURI) ? attendeeInitDict.delegateURI : "";
+        _self.contactRef   = (attendeeInitDict.contactRef) ? attendeeInitDict.contactRef : "";
+    } else {
+        _self.uri          = "";
+        _self.name         = "";
+        _self.role         = "";
+        _self.status       = "";
+        _self.RSVP         = "";
+        _self.type         = "";
+        _self.group        = "";
+        _self.delegatorURI = "";
+        _self.delegateURI  = "";
+        _self.contactRef   = "";
+    }
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/filesystem', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var event = require('ripple/event'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    utils = require('ripple/utils'),
+    dbfs  = require('ripple/platform/tizen/1.0/dbfs'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    _maxPathLength = 256,
+    _virtualRoots = ["documents", "images", "music", "videos", "downloads", "wgt-package", "wgt-private", "wgt-private-tmp", "removable", "attachments"],
+    _security = {
+        "http://tizen.org/api/filesystem": [],
+        "http://tizen.org/api/filesystem.read": ["copyTo", "moveTo", "createDirectory", "createFile", "deleteDirectory", "deleteFile", "openStreamR"],
+        "http://tizen.org/api/filesystem.write": ["readAsText", "openStreamW"],
+        all: true
+    },
+    _realRoots = dbfs.roots,
+    _r2vmap = {},
+    _v2rmap = {},
+    _initialized = false,
+    _readOnly  = false,
+    _writeOnly = false,
+    _defaultMode = "rw",
+    _storages = [], // filesystem storages
+    _observers = [],
+    File,
+    FileStream,
+    FileFilter,
+    FileSystemStorage;
+
+function _isValidChar(c) {
+    return  (c >= '0' && c <= '9') ||
+        (c >= 'a' && c <= 'z') ||
+        (c >= 'A' && c <= 'Z') ||
+        (c === ' ') ||
+        (c === '_') ||
+        (c === '-') ||
+        (c === '.');
+}
+
+function _isValidFileName(name) {
+    var _valid = true,
+        _c;
+
+    if (name === '' || name === '.' || name === '..' || (name.length > _maxPathLength)) {
+        _valid = false;
+    } else {
+        for (_c = 0; _c < name.length; _c++) {
+            if (!_isValidChar(name[_c])) {
+                _valid = false;
+                break;
+            }
+        }
+    }
+
+    return _valid;
+}
+
+function _initialize() {
+    var _i;
+
+    _storages.push(FileSystemStorage("InternalFlash", "INTERNAL", "MOUNTED" ));
+    _storages.push(FileSystemStorage("MMC", "EXTERNAL", "REMOVED"));
+    dbfs.initialize();
+
+    // set up the map between real path and virtual path
+    for (_i = 0; _i < _virtualRoots.length; _i++) {
+        _r2vmap[_realRoots[_i]] = _virtualRoots[_i];
+    }
+
+    utils.forEach(_r2vmap, function (value, key) {
+        _v2rmap[value] = key;
+    });
+}
+
+function _resolveSync(srcLocation, onSuccess, onError, accessMode) {
+    var _parts = srcLocation.replace(/\/$/, '').split("/"),
+        _header, _fullPath,
+        _i;
+
+    // TODO: Initialize at bootstrap and emulatorBridge.link
+    if (!_initialized) {
+        _initialize();
+        _initialized = true;
+    }
+
+    for (_i = 0; _i < _parts.length; _i++) {
+        if (!_isValidFileName(_parts[_i])) {
+            if (onError) {
+                onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
+            }
+            return;
+        }
+    }
+
+    _header = _v2rmap[_parts[0]];
+    if (_header === undefined) {
+        if (onError) {
+            onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
+        }
+        return;
+    }
+
+    if (_parts.length === 1) {
+        _fullPath = _header;
+    } else {
+        _fullPath = _header + "/" + _parts.splice(1, _parts.length - 1).join("/");
+    }
+
+    dbfs.stat(_fullPath,
+            function (entry) {
+                onSuccess(new File(entry, accessMode));
+            },
+            function () {
+                if (onError) {
+                    onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                }
+            });
+}
+
+function _resolveAsync(onSuccess, onError, srcLocation, accessMode) {
+    _resolveSync(srcLocation,
+                function (file) {
+                    setTimeout(function () {
+                        onSuccess(file);
+                    }, 1);
+                },
+                function (e) {
+                    setTimeout(function () {
+                        onError(e);
+                    }, 1);
+                },
+                accessMode);
+}
+
+File = function (entry, mode) {
+    var _entry = entry,
+        _mode = mode,
+        _parent,
+        _self;
+
+    function _r2v(rpath) {
+        var i, v, r, regExp;
+
+        for (i = 0; i < _virtualRoots.length; i++) {
+            v = _virtualRoots[i];
+            r = _v2rmap[v];
+            if (rpath.match("^" + r)) {
+                regExp = new RegExp("^" + r);
+                return rpath.replace(regExp, v);
+            }
+        }
+
+        return "";
+    }
+
+    function _v2r(vpath) {
+        var i, v, r, regExp;
+
+        for (i = 0; i < _virtualRoots.length; i++) {
+            v = _virtualRoots[i];
+            r = _v2rmap[v];
+            if (vpath.match("^" + v)) {
+                regExp = new RegExp("^" + v);
+                return vpath.replace(regExp, r);
+            }
+        }
+
+        return "";
+    }
+
+    function _copyMoveInternal(onSuccess, onError, src, dst, overwrite, func) {
+        var _srcName = String(src),
+            _dstName = String(dst),
+            _src = null,
+            _dst = null,
+            _error = false,
+            _dstParent = null,
+            _dstParts  = _dstName.split("/"),
+            _dstParentName = _dstParts.splice(0, _dstParts.length - 1).join("/");
+
+        if (!_entry.isDirectory) {
+            if (onError) {
+                setTimeout(function () {
+                    onError(new WebAPIError(errorcode.IO_ERR));
+                }, 1);
+            }
+            return undefined;
+        }
+
+        _resolveSync(_srcName,
+                function (file) {
+                    _src = file;
+                },
+                function (e) {
+                    setTimeout(function () {
+                        onError(e);
+                    }, 1);
+                },
+                _mode);
+
+        if (_src) {
+            if (_src.parent.fullPath === _self.fullPath) {
+                if (!_readOnly && _mode !== "r") {
+                    _resolveSync(_dstParentName,
+                            function (file) {
+                                _dstParent = file;
+                            },
+                            function (e) {
+                                setTimeout(function () {
+                                    onError(e);
+                                }, 1);
+                            },
+                            _mode);
+
+                    if (_dstParent === null) {
+                        return undefined;
+                    }
+
+                    _resolveSync(_dstName,
+                            function (file) {
+                                _dst = file;
+                            },
+                            function (e) {
+                                if (e.code !== errorcode.NOT_FOUND_ERR) {
+                                    setTimeout(function () {
+                                        onError(e);
+                                    }, 1);
+                                    _error = true;
+                                }
+                            },
+                            _mode);
+
+                    if (_error) {
+                        return undefined;
+                    }
+
+                    if (_src.isFile) {
+                        if (_dst === null) {
+                            func(_v2r(_srcName), _v2r(_dstName),
+                                    function () {
+                                        setTimeout(function () {
+                                            onSuccess();
+                                        }, 1);
+                                    },
+                                    function () {});
+                            return null;
+                        } else {
+                            if (_dst.isFile && Boolean(overwrite) && (_srcName !== _dstName)) {
+                                func(_v2r(_srcName), _v2r(_dstName),
+                                        function () {
+                                            setTimeout(function () {
+                                                onSuccess();
+                                            }, 1);
+                                        },
+                                        function () {});
+                                return null;
+                            } else {
+                                setTimeout(function () {
+                                    onError(new WebAPIError(errorcode.IO_ERR));
+                                }, 1);
+                            }
+                        }
+                    } else {
+                        if (_dst === null) {
+                            func(_v2r(_srcName), _v2r(_dstName),
+                                function () {
+                                    setTimeout(function () {
+                                        onSuccess();
+                                    }, 1);
+                                },
+                                function () {});
+                            return null;
+                        } else {
+                            setTimeout(function () {
+                                onError(new WebAPIError(errorcode.IO_ERR));
+                            }, 1);
+                        }
+                    }
+                } else {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                }
+            } else {
+                if (onError) {
+                    setTimeout(function () {
+                        onError(new WebAPIError(errorcode.IO_ERR));
+                    }, 1);
+                }
+            }
+        }
+
+        return undefined;
+    }
+
+    _self = {
+        toURI: function () {
+            return "file://" + _entry.fullPath;
+        },
+        listFiles: function (onSuccess, onError, filter) {
+            var _filter = Object(filter),
+                _filterName = _filter.name,
+                _startModified = _filter.startModified,
+                _endModified   = _filter.endModified;
+
+            function _matchName(fileName) {
+                var _matched = true,
+                    _name1 = String(_filterName).toLowerCase(),
+                    _name2 = fileName.toLowerCase(),
+                    _pattern;
+
+                if (_filterName !== undefined && _filterName !== null) {
+                    if (!_name1.match("\\\\%")) {
+                        if (_name1.match("%")) {
+                            _pattern = new RegExp("^" + _name1.replace(/%/g, ".*") + "$");
+                            _matched = _name2.match(_pattern) ? true : false;
+                        } else {
+                            _matched = (_name1 === _name2);
+                        }
+                    } else {
+                        // % is not allowed as a part of file name
+                        _matched = false;
+                    }
+                }
+
+                return _matched;
+            }
+
+            function _matchDate(date) {
+                var _matched = true;
+
+                if (_startModified !== undefined && _startModified !== null) {
+                    _matched = (date.getTime() >= _startModified.getTime());
+                }
+
+                if (_matched && (_endModified !== undefined && _endModified !== null)) {
+                    _matched = (date.getTime() <= _endModified.getTime());
+                }
+
+                return _matched;
+            }
+
+            function _matchFilter(entry) {
+                return _matchName(entry.name) && _matchDate(entry.lastModifiedDate);
+            }
+
+            function _listFiles() {
+                var _files = [];
+
+                if ((_startModified !== undefined && !tizen1_utils.isValidDate(_startModified)) ||
+                    (_endModified !== undefined && !tizen1_utils.isValidDate(_endModified))) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                if (!_entry.isDirectory) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.IO_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                utils.forEach(_entry.children, function (child) {
+                    if (_matchFilter(child)) {
+                        _files.push(new File(child, _mode));
+                    }
+                });
+
+                setTimeout(function () {
+                    onSuccess(_files);
+                }, 1);
+
+                return null;
+            }
+
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "listFiles", _listFiles);
+        },
+        openStream: function (mode, onSuccess, onError, encoding) {
+            function _openStream() {
+                var  _openMode = String(mode),
+                    _encoding = encoding ? String(encoding) : "UTF-8";
+
+                if (_openMode !== "r" && _openMode !== "w" && _openMode !== "a") {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                if (!_security.all && ((!_security.openStreamR && _openMode === "r") || (!_security.openStreamW && _openMode === "w"))) {
+                    throw new WebAPIError(errorcode.SECURITY_ERR);
+                }
+
+                if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                if (((_readOnly || _mode === "r") && (_openMode === "w" || _openMode === "a")) ||
+                    (_writeOnly && _openMode === "r")) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                setTimeout(function () {
+                    onSuccess(new FileStream(_entry, _openMode, _encoding));
+                }, 1);
+
+                return null;
+            }
+
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "openStream", _openStream);
+        },
+        readAsText: function (onSuccess, onError, encoding) {
+            if (!_security.all && !_security.readAsText) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            function _readAsText() {
+                var _encoding = encoding ? String(encoding) : "UTF-8";
+                if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                if (_writeOnly) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                if (_self.isFile) {
+                    dbfs.read(_entry.fullPath,
+                            function (data) {
+                                setTimeout(function () {
+                                    onSuccess(data);
+                                }, 1);
+                            },
+                            function () {});
+                    return null;
+                } else {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.IO_ERR));
+                        }, 1);
+                    }
+                }
+
+                return undefined;
+            }
+
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "readAsText", _readAsText);
+        },
+        copyTo: function (src, dst, overwrite, onSuccess, onError) {
+            if (!_security.all && !_security.copyTo) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            function _copyTo() {
+                return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.cp);
+            }
+
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "copyTo", _copyTo);
+        },
+        moveTo: function (src, dst, overwrite, onSuccess, onError) {
+            if (!_security.all && !_security.moveTo) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            function _moveTo() {
+                return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.mv);
+            }
+
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "moveTo", _moveTo);
+        },
+        createDirectory: function (dirPath) {
+            var _path  = String(dirPath),
+                _parts = _path.replace(/\/$/, "").split("/"),
+                _dir   = null,
+                _exist = null,
+                _current = _entry.fullPath,
+                _i;
+
+            if (!_security.all && !_security.createDirectory) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            function onSuccess(entry) {
+                _dir = entry;
+            }
+
+            for (_i = 0; _i < _parts.length; _i++) {
+                if (!_isValidFileName(_parts[_i])) {
+                    throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+                }
+            }
+
+            if (!entry.isDirectory) {
+                throw new WebAPIError(errorcode.IO_ERR);
+            }
+
+            _exist = _parts.reduce(function (obj, token) {
+                return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
+            }, _entry);
+
+            if (_exist) {
+                throw new WebAPIError(errorcode.IO_ERR);
+            }
+
+            if (_readOnly || _mode === "r") {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            for (_i = 0; _i < _parts.length; _i++) {
+                _current = _current + "/" + _parts[_i];
+                dbfs.mkdir(_current, onSuccess);
+            }
+
+            return new File(_dir, _mode);
+        },
+        createFile: function (filePath) {
+            var _name = String(filePath),
+                _file = null;
+
+            if (!_security.all && !_security.createFile) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            if (!_isValidFileName(_name)) {
+                throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+            }
+
+            if (!entry.isDirectory || (_entry.children && _entry.children[_name])) {
+                throw new WebAPIError(errorcode.IO_ERR);
+            }
+
+            if (_readOnly || _mode === "r") {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            dbfs.touch(_entry.fullPath + "/" + _name,
+                        function (entry) {
+                            _file = new File(entry, _mode);
+                        },
+                        function () {});
+
+            return _file;
+        },
+        resolve: function (filePath) {
+            var _fullPath = _self.fullPath + "/" + String(filePath),
+                _file = null;
+
+            if (!_entry.isDirectory) {
+                throw new WebAPIError(errorcode.IO_ERR);
+            }
+
+            _resolveSync(_fullPath,
+                    function (file) {
+                        _file = file;
+                    },
+                    function (e) {
+                        throw (e);
+                    },
+                    _mode);
+
+            return _file;
+        },
+        deleteDirectory: function (directory, recursive, onSuccess, onError) {
+            if (!_security.all && !_security.deleteDirectory) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            function _deleteDirectory() {
+                var _dir = null,
+                    _dirName = String(directory);
+                _resolveSync(_dirName,
+                        function (file) {
+                            _dir = file;
+                        },
+                        function (e) {
+                            setTimeout(function () {
+                                onError(e);
+                            }, 1);
+                        },
+                        _mode);
+
+                if (_dir) {
+                    if (_dir.isDirectory &&
+                        _dir.parent.fullPath === _self.fullPath &&
+                        (!recursive && _dir.length === 0)) {
+                        if (!_readOnly && _mode !== "r") {
+                            dbfs.rmdir(_v2r(_dirName),
+                                    function () {
+                                        setTimeout(function () {
+                                            onSuccess();
+                                        }, 1);
+                                    },
+                                    function () {});
+                            return null;
+                        } else {
+                            if (onError) {
+                                setTimeout(function () {
+                                    onError(new WebAPIError(errorcode.SECURITY_ERR));
+                                }, 1);
+                            }
+                        }
+                    } else {
+                        if (onError) {
+                            setTimeout(function () {
+                                onError(new WebAPIError(errorcode.IO_ERR));
+                            }, 1);
+                        }
+                    }
+                }
+
+                return undefined;
+            }
+
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "deleteDirectory", _deleteDirectory);
+        },
+        deleteFile: function (fileName, onSuccess, onError) {
+            if (!_security.all && !_security.deleteFile) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            function _deleteFile() {
+                var _file = null;
+                _resolveSync(String(fileName),
+                        function (file) {
+                            _file = file;
+                        },
+                        function (e) {
+                            if (onError) {
+                                setTimeout(function () {
+                                    onError(e);
+                                }, 1);
+                            }
+                        },
+                        _mode);
+
+                if (_file) {
+                    if (_file.isFile && _file.parent.fullPath === _self.fullPath) {
+                        if (!_readOnly && _mode !== "r") {
+                            dbfs.rm(_v2r(fileName),
+                                    function () {
+                                        setTimeout(function () {
+                                            onSuccess();
+                                        }, 1);
+                                    },
+                                    function () {});
+                            return null;
+                        } else {
+                            if (onError) {
+                                setTimeout(function () {
+                                    onError(new WebAPIError(errorcode.SECURITY_ERR));
+                                }, 1);
+                            }
+                        }
+                    } else {
+                        if (onError) {
+                            setTimeout(function () {
+                                onError(new WebAPIError(errorcode.IO_ERR));
+                            }, 1);
+                        }
+                    }
+                }
+
+                return undefined;
+            }
+
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "deleteFile", _deleteFile);
+        }
+    };
+
+    _self.__defineGetter__("parent", function () {
+        var _parts = _self.fullPath.split("/");
+
+        if (_parent === undefined) {
+            if (_parts.length === 1) {
+                // virtual root's parent is null
+                _parent = null;
+            } else {
+                _resolveSync(_parts.splice(0, _parts.length - 1).join("/"),
+                        function (file) {
+                            _parent = file;
+                        },
+                        function () {},
+                        _mode);
+            }
+            return _parent;
+        } else {
+            return _parent;
+        }
+    });
+
+    _self.__defineGetter__("readOnly", function () {
+        return false;
+    });
+
+    _self.__defineGetter__("isFile", function () {
+        return !_entry.isDirectory;
+    });
+
+    _self.__defineGetter__("isDirectory", function () {
+        return _entry.isDirectory;
+    });
+
+    _self.__defineGetter__("created", function () {
+        return undefined;
+    });
+
+    _self.__defineGetter__("modified", function () {
+        if (_entry.isDirectory) {
+            return undefined;
+        } else {
+            return _entry.lastModifiedDate;
+        }
+    });
+
+    _self.__defineGetter__("path", function () {
+        var _parts = _self.fullPath.split("/");
+
+        if (_parts.length === 1) {
+            // virtual root
+            return _parts.join("");
+        } else {
+            return _parts.splice(0, _parts.length - 1).join("/") + "/";
+        }
+    });
+
+    _self.__defineGetter__("name", function () {
+        return _entry.name;
+    });
+
+    _self.__defineGetter__("fullPath", function () {
+        return _r2v(_entry.fullPath);
+    });
+
+    _self.__defineGetter__("fileSize", function () {
+        if (_entry.isDirectory) {
+            return undefined;
+        } else {
+            return _entry.data.length;
+        }
+    });
+
+    _self.__defineGetter__("length", function () {
+        var _l = 0;
+        if (_entry.isDirectory) {
+            utils.forEach(_entry.children, function () {
+                _l++;
+            });
+            return _l;
+        } else {
+            return undefined;
+        }
+    });
+
+    return _self;
+};
+
+FileStream = function (entry, mode, encoding) {
+    var _entry = entry,
+        _data = entry.data,
+        _mode = mode,
+        _position = (_mode === "a" ? _data.length : 0),
+        _self;
+
+    _self = {
+        close: function () {
+            var _element;
+            if (mode === "a" || mode === "w") {
+                dbfs.write(_entry.fullPath, _data, function () {}, function () {});
+            }
+            for (_element in _self) {
+                delete _self[_element];
+            }
+        },
+        read: function (charCount) {
+            var _count  = charCount | 0,
+                _substr = _data.substring(_position, _position + _count);
+
+            if (_position + _count > _data.length) {
+                _position = _data.length;
+            } else {
+                _position += _count;
+            }
+
+            return _substr;
+        },
+        readBytes: function (byteCount) {
+            var _substr = _self.read(byteCount),
+                _bytes = [],
+                _i;
+
+            for (_i = 0; _i < _substr.length; _i++) {
+                _bytes.push(_substr.charCodeAt(_i));
+            }
+
+            return _bytes;
+        },
+        readBase64: function (byteCount) {
+            var _substr = _self.read(byteCount);
+
+            return window.atob(_substr);
+        },
+        write: function (stringData) {
+            var _stringData = String(stringData),
+                _substr = _data.substring(0, _position);
+
+            _data = _substr.concat(_stringData);
+            _position = _data.length;
+        },
+        writeBytes: function (byteData) {
+            _self.write(String.fromCharCode.apply(String, byteData));
+        },
+        writeBase64: function (base64Data) {
+            _self.write(window.btoa(String(base64Data)));
+        }
+    };
+
+    _self.__defineGetter__("eof", function () {
+        return _position === _data.length;
+    });
+
+    _self.__defineGetter__("position", function () {
+        return _position;
+    });
+
+    _self.__defineSetter__("position", function (value) {
+        var _value = value | 0;
+
+        if (_value >= 0 && _value <= _data.length) {
+            _position = _value;
+        } else {
+            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+        }
+    });
+
+    _self.__defineGetter__("bytesAvailable", function () {
+        return (_data.length - _position) || -1;
+    });
+
+    return _self;
+};
+
+FileFilter = function (name, startModified, endModified, startCreated, endCreated) {
+    var _self = {
+        name: name,
+        startModified: utils.copy(startModified),
+        endModified: utils.copy(endModified),
+        endCreated: utils.copy(endCreated)
+    };
+
+    return _self;
+};
+
+FileSystemStorage = function (label, type, state) {
+    var _self = {
+        label: label,
+        type: type,
+        state: state
+    };
+
+    return _self;
+};
+
+module.exports = {
+    maxPathLength: _maxPathLength,
+    resolve: function (srcLocation, onSuccess, onError, accessMode) {
+        function _resolve() {
+            var _mode = accessMode ? String(accessMode) : _defaultMode;
+
+            if (_mode === "r" || _mode === "rw") {
+                _resolveAsync(onSuccess, onError, String(srcLocation), _mode);
+                return null;
+            } else {
+                if (onError) {
+                    setTimeout(function () {
+                        onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
+                    }, 1);
+                }
+            }
+            return undefined;
+        }
+
+        return tizen1_utils.validateTypeMismatch(onSuccess, onError, "resolve", _resolve);
+    },
+
+    getStorage: function (label, onSuccess, onError) {
+        var i, storage = null, _label = String(label);
+
+        _storages.some(function (value) {
+            if (value.label === _label) {
+                storage = utils.copy(value);
+                setTimeout(function () {
+                    onSuccess(storage);
+                }, 1);
+                return true;
+            }
+        });
+
+        if (!storage) {
+            if(onError) {
+                setTimeoout(function () {
+                    onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                }, 1);
+
+            } else {
+                throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+            }
+        }
+    },
+
+    listStorages: function (onSuccess, onError) {
+        function _listStorages() {
+            setTimeout(function () {
+                onSuccess(utils.copy(_storages));
+            }, 1);
+        }
+
+        return tizen1_utils.validateTypeMismatch(onSuccess, onError, "listStorages", _listStorages);
+    },
+
+    addStorageStateChangeListener: function(onSuccess, onError) {
+        function _addStorageStateChangeListener() {
+            var watchId = (new Date()).getTime() || 0;
+            _observers[watchId] = function(storage) {//storage is which state is changed
+                       onSuccess(storage);
+                   };
+
+            // This event should be triggered from outside
+                   event.on("StateChange", _observers[watchId]);
+                   return Number(watchId);
+        }
+
+        return tizen1_utils.validateTypeMismatch(onSuccess, onError, "addStorageStateChangeListener", _addStorageStateChangeListener);
+    },
+
+    removeStorageStateChangeListener: function (watchId) {
+        if (!watchId || typeof watchId !== "number") {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+        watchId = String(watchId);
+
+        if (_observers[watchId]) {
+            event.deleteEventHandler("StateChange", _observers[watchId]);
+            delete _observers[watchId];
+        } else {
+            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+        }
+    },
+
+    handleSubFeatures: function (subFeatures) {
+        function setSecurity(_security) {
+            return function (method) {
+                _security[method] = true;
+            };
+        }
+
+        for (var subFeature in subFeatures) {
+            if (_security[subFeature].length === 0) {
+                _security.all = true;
+                return;
+            }
+            _security.all = false;
+            utils.forEach(_security[subFeature], setSecurity);
+        }
+    }
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/CalendarAlarm', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    TZDate = require('ripple/platform/tizen/1.0/TZDate'),
+    TimeDuration = require('ripple/platform/tizen/1.0/TimeDuration'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    _alarmMethods = ["SOUND", "DISPLAY"];
+
+module.exports = function (triggerTime, method, description) {
+    var absoluteDate = null,
+        before = null,
+        isValid = false,
+        _self;
+
+    if (triggerTime instanceof TZDate) {
+        absoluteDate = new TZDate(triggerTime);
+    } else if (triggerTime instanceof TimeDuration) {
+        before = triggerTime;
+    } else {
+        throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+    }
+
+    isValid = utils.arrayContains(_alarmMethods, method);
+    if (!isValid)
+        throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+
+    if (method.equals("DISPLAY") && description === null)
+        throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+
+    _self.absoluteDate = absoluteDate;
+    _self.before       = before;
+    _self.method       = method;
+    _self.description  = description;
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/GeocodeResult', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+var SimpleCoordinates = require('ripple/platform/tizen/1.0/SimpleCoordinates');
+
+module.exports = function (lat, lon) {
+    var _self, _coordinates, jsonStr, jsonObj;
+
+    _coordinates = new SimpleCoordinates(lat, lon);
+
+    jsonObj = { 
+        "type" : "Point",
+        "coordinates" : [lat, lon]
+    };
+
+    jsonStr = JSON.stringify(jsonObj);
+
+    _self = {
+        coordinates : _coordinates,
+        toGeoJSON : function () {
+            return jsonStr;
+        }
+    };
+    return _self;
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/CalendarTask', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var TZDate = require('ripple/platform/tizen/1.0/TZDate'),
+    CalendarItem = require('ripple/platform/tizen/1.0/CalendarItem'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    SimpleCoordinates = require('ripple/platform/tizen/1.0/SimpleCoordinates');
+
+module.exports = function (taskInitDict) {
+    var _self;
+
+    _self = new CalendarItem("TASK");
+
+    if ((taskInitDict !== undefined) && (taskInitDict !== null)) {
+        _self.endDate       = taskInitDict.endDate;
+        _self.completedDate = taskInitDict.completedDate;
+        _self.progress      = taskInitDict.progress;
+        if (taskInitDict.description) {
+            _self.description = String(taskInitDict.description);
+        }
+        if (taskInitDict.summary) {
+            _self.summary = String(taskInitDict.summary);
+        }
+        if (taskInitDict.isAllDay && (typeof taskInitDict.isAllDay === "boolean")) {
+            _self.isAllDay = taskInitDict.isAllDay;
+        }
+        if (taskInitDict.startDate && tizen1_utils.isValidTZDate(taskInitDict.startDate)) {
+            _self.startDate = taskInitDict.startDate;
+        }
+        if (taskInitDict.duration && (typeof taskInitDict.duration === "object")) {
+            _self.duration = new TZDate(taskInitDict.duration);
+        }
+        if (taskInitDict.location) {
+            _self.location = String(taskInitDict.location);
+        }
+        if (taskInitDict.geolocation && taskInitDict.geolocation.latitude && taskInitDict.geolocation.longitude) {
+            _self.geolocation = new SimpleCoordinates(taskInitDict.geolocation.latitude, taskInitDict.geolocation.longitude);
+        }
+        if (taskInitDict.organizer) {
+            _self.organizer = String(taskInitDict.organizer);
+        }
+        if (taskInitDict.visibility) {
+            _self.visibility = String(taskInitDict.visibility);
+        }
+        if (taskInitDict.status) {
+            _self.status = String(taskInitDict.status);
+        }
+        if (taskInitDict.priority) {
+            _self.priority = String(taskInitDict.priority);
+        }
+        if (taskInitDict.alarms && tizen1_utils.isValidArray(taskInitDict.alarms)) {
+            var isInValid = false;
+            taskInitDict.alarms.some(function (alarm) {
+                if (!alarm || alarm.method === undefined) {// 'method' is CalendarAlarm's property.
+                    isInValid = true;
+                    return;
+                }
+            });
+            if (!isInValid) {
+                _self.alarms = taskInitDict.alarms;
+            }
+        }
+        if (taskInitDict.categories && tizen1_utils.isValidArray(taskInitDict.categories)) {
+            var isInValid = false;
+            taskInitDict.categories.every(function (categorie) {
+                if (!categorie || typeof categorie !== "string") {
+                    isInValid = true;
+                    return;
+                }
+            });
+            if (!isInValid) {
+                _self.categories = taskInitDict.categories;
+            }
+        }
+        if (taskInitDict.attendees && tizen1_utils.isValidArray(taskInitDict.attendees)) {
+            var isInValid = false;
+            taskInitDict.attendees.some(function (attendee) {
+                if (!attendee || attendee.uri === undefined) {// 'uri' is CalendarAttendee's property.
+                    isInValid = true;
+                    return;
+                }
+            });
+            if (!isInValid) {
+                _self.attendees = taskInitDict.attendees;
+            }
+        }
+    } else {
+        _self.endDate       = new TZDate();
+        _self.completedDate = new TZDate();
+        _self.progress      = 0;
+    }
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/POIFilter', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (attributeName, value) {
+    var _self;
+
+    _self = {
+        attributeName: attributeName,
+        value: value
+    };
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/contact', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    Contact = require('ripple/platform/tizen/1.0/ContactBase'),
+    ContactName = require('ripple/platform/tizen/1.0/ContactName'),
+    ContactOrganization = require('ripple/platform/tizen/1.0/ContactOrganization'),
+    ContactWebSite = require('ripple/platform/tizen/1.0/ContactWebSite'),
+    ContactAnniversary = require('ripple/platform/tizen/1.0/ContactAnniversary'),
+    ContactAccount = require('ripple/platform/tizen/1.0/ContactAccount'),
+    ContactAddress = require('ripple/platform/tizen/1.0/ContactAddress'),
+    ContactPhoneNumber = require('ripple/platform/tizen/1.0/ContactPhoneNumber'),
+    ContactEmailAddress = require('ripple/platform/tizen/1.0/ContactEmailAddress'),
+    PendingObject = require('ripple/platform/tizen/1.0/pendingObject'),
+    PendingOperation = require('ripple/platform/tizen/1.0/pendingoperation'),
+    _self,
+    _KEY = "tizen1-contact",
+    _security = {
+        "http://tizen.org/api/contact": [],
+        "http://tizen.org/api/contact.read": ["find", "addChangeListener"],
+        "http://tizen.org/api/contact.write": ["add", "addBatch", "update", "updateBatch", 
+        "remove", "removeBatch"],
+        all: true
+    },
+    _addressBooks = [],
+    _PENDING_TIME = 10;
+
+function _pendingOperate(operate) {
+    var pendingObj, pendingOperation, i, argumentVector = [];
+
+    for (i = 0; i < arguments.length - 1; i++) {
+        argumentVector[i] = arguments[i + 1];
+    }
+
+    pendingObj = new PendingObject();
+
+    pendingObj.pendingID = window.setTimeout(function () {
+        pendingObj.setCancelFlag(false);
+        operate.apply(this, argumentVector);
+    }, _PENDING_TIME);
+
+    pendingOperation = new PendingOperation(pendingObj);
+
+    return pendingOperation;
+}
+
+function _validateCallbackType(onSuccess, onError, callback) {
+    if (onSuccess) {
+        tizen1_utils.validateArgumentType(onSuccess, "function",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+    }
+    if (onError) {
+        tizen1_utils.validateArgumentType(onError, "function",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+    }
+
+    return callback && callback();
+}
+
+function _checkContactProperties(prop, checkIDEmpty) {
+    var i;
+
+    if (prop) {
+        if (checkIDEmpty === true) {
+            /* id should not be exist */
+            if (prop.id !== null && prop.id !== undefined) {
+                return false;
+            }
+        } else {
+            if (typeof prop.id !== "string") {
+                return false;
+            }
+        }
+
+        /* if prop.addresses exists, it must be a array */
+        if (prop.addresses && !tizen1_utils.isValidArray(prop.addresses)) {
+            return false;
+        }
+
+        /* if prop.phoneNumbers exists, it must be a array */
+        if (prop.phoneNumbers && !tizen1_utils.isValidArray(prop.phoneNumbers)) {
+            return false;
+        }
+
+        /* if prop.emails exists, it must be a array */
+        if (prop.emails && !tizen1_utils.isValidArray(prop.emails)) {
+            return false;
+        }
+
+        /* if prop.birthday exists, its type is Date */
+        if (prop.birthday && !tizen1_utils.isValidDate(prop.birthday)) {
+            return false;
+        }
+
+        /* if prop.anniversaries exists, it must be a array */
+        if (prop.anniversaries && !tizen1_utils.isValidArray(prop.anniversaries)) {
+            for (i = 0; i < prop.anniversaries; i++) {
+                if (tizen1_utils.isValidDate(prop.anniversaries[i].date)) {
+                    return false;
+                }
+            }
+        }
+
+        /* if prop.notes exists, it must be a array */
+        if (prop.notes && !tizen1_utils.isValidArray(prop.notes)) {
+            return false;
+        }
+
+        /* if prop.urls exists, it must be a array */
+        if (prop.urls && !tizen1_utils.isValidArray(prop.urls)) {
+            return false;
+        }
+
+        /* if prop.isFavorite exists, its type is boolean */
+        if (prop.isFavorite && typeof prop.isFavorite !== "boolean") {
+            return false;
+        }
+
+        /* if prop.ringtoneURI exists, its type is string */
+        if (prop.ringtoneURI && typeof prop.ringtoneURI !== "string") {
+            return false;
+        }
+
+        /* if prop.categories exists, it must be a array */
+        if (prop.categories && !tizen1_utils.isValidArray(prop.categories)) {
+            return false;
+        }
+    }
+
+    /* pass all check */
+    return true;
+}
+
+/* check filter type (it's a recursive function)
+   0: It is not a filter
+   1: CompositeFilter
+   2: AttributeFilter
+   3: AttributeRangeFilter
+ */
+function _filterType(filter) {
+    var i = 0, ret;
+
+    if (Object.prototype.toString.call(filter) !== "[object Object]") {
+        return 0; // 0: it is not a filter
+    }
+
+    /* check if it is CompositFilter or not */
+    if (filter.type !== null && filter.type !== undefined) {
+        /* attribute 'type' of CompositeFilter must be "UNION" or "INTERSECTION" */
+        if (filter.type === "UNION" || filter.type === "INTERSECTION") {
+            /*attribute 'filters' of CompositeFilter must be AbstractFilter array */
+            if (tizen1_utils.isValidArray(filter.filters)) {
+                for (i = 0; i < filter.filters.length; i++) {
+                    /* recursive call */
+                    if (_filterType(filter.filters[i]) === 0) {
+                        return 0; // 0: it is not a filter
+                    }
+                }
+            } else {
+                return 0; // 0: it is not a filter
+            }
+        } else {
+            return 0; // 0: it is not a filter
+        }
+        return 1; // CompositeFilter
+    }
+
+    /* AttributeFilter or AttributeRangeFilter must have attributeName */
+    if (filter.attributeName === null || filter.attributeName === undefined) {
+        return 0; // 0: it is not a filter
+    } else {
+        ret = 2; // assume it is an AttributeFilter
+        if ((filter.initialValue !== null || filter.initialValue !== undefined) ||
+            (filter.endValue !== null || filter.endValue !== undefined)) {
+            ret = 3; // AttributeRangeFilter
+        }
+        return ret;
+    }
+}
+
+function ContactPublic(prop) {
+    var _self;
+
+    if (typeof prop.id !== "string") {
+        return undefined;
+    }
+    if (!tizen1_utils.isValidDate(prop.lastUpdated)) {
+        return undefined;
+    }
+    _self = new Contact(prop);
+
+    _self.__defineGetter__("id", function () {
+        return prop.id;
+    });
+    _self.__defineGetter__("lastUpdated", function () {
+        return prop.lastUpdated;
+    });
+    return _self;
+}
+
+function ContactPrivate(prop, newID) {
+    var _self;
+    _self = new Contact(prop);
+    if (newID === true) {
+        _self.id = Math.uuid(undefined, 16);
+    } else {
+        _self.id = prop.id;
+    }
+    _self.lastUpdated = new Date();
+    return _self;
+}
+
+function AddressBook(id, name, readOnly, contacts) {
+    var addressBook;
+    
+    addressBook = {
+        _contacts : contacts,
+        _listenerCount : 0,
+        _listeners : {},
+        get : function (id) {
+            if (typeof id !== "string") {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+
+            if (this._contacts[id]) {
+                return new ContactPublic(this._contacts[id]);
+            } else {
+                throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+            }
+        },
+        add : function (contact) {
+            var item, item2;
+            if (!_security.all && !_security.add) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            if (Object.prototype.toString.call(contact) !== "[object Object]") {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+
+            if (this.readOnly === true) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            if (_checkContactProperties(contact, true) === false) {
+                throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+            }
+            item = new ContactPrivate(contact, true);
+            this._contacts[item.id] = item;
+            _save();
+
+            contact.id = item.id;
+            contact.lastUpdated = item.lastUpdated;
+
+            /* send changed notification */
+            utils.forEach(this._listeners, function (listenerCB) {
+                item2 = new ContactPublic(item);
+                listenerCB.oncontactsadded([item2]);
+            });
+        },
+        addBatch : function (contacts, successCB, errorCB) {
+            var inner = this, 
+                item, item2, listenArray;
+            function _addBatch() {
+                var ret, i;
+                if (!_security.all && !_security.addBatch) {
+                    throw new WebAPIError(errorcode.SECURITY_ERR);
+                }
+
+                if (!tizen1_utils.isValidArray(contacts)) {
+                    throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                } else {
+                    if (contacts.length === 0) {
+                        throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+                    }
+                    for (i = 0; i < contacts.length; i++) {
+                        if (_checkContactProperties(contacts[i], true) === false) {
+                            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+                        }
+                    }
+                }
+                if (inner.readOnly === true) {
+                    throw new WebAPIError(errorcode.SECURITY_ERR);
+                }
+
+                ret = _pendingOperate(function () {
+                    var i;
+                    for (i = 0; i < contacts.length; i++) {
+                        item = new ContactPrivate(contacts[i], true);
+                        contacts[i] = new ContactPublic(item);
+                        inner._contacts[item.id] = item;
+                    }
+                    _save();
+                    if (successCB) {
+                        successCB(contacts);
+                    }
+
+                    /* send changed notification */
+                    utils.forEach(inner._listeners, function (listenerCB) {
+                        listenArray = [];
+                        for (i = 0; i < contacts.length; i++) {
+                            item2 = new ContactPublic(contacts[i]);
+                            listenArray.push(item2);
+                        }
+                        listenerCB.oncontactsadded(listenArray);
+                    });
+                });
+                return;
+            }
+
+            _validateCallbackType(successCB, errorCB, _addBatch);
+        },
+        update : function (contact) {
+            var item, item2, inner = this;
+            if (!_security.all && !_security.update) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            if (Object.prototype.toString.call(contact) !== "[object Object]") {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+
+            if (this.readOnly === true) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            if (_checkContactProperties(contact, false) === false) {
+                throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+            }
+            if (contact.id && this._contacts[contact.id]) {
+                item = new ContactPrivate(contact, false);
+                this._contacts[item.id] = item;
+                _save();
+            } else {
+                throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+            }
+
+            /* send changed notification */
+            utils.forEach(this._listeners, function (listenerCB) {
+                item2 = new ContactPublic(inner._contacts[contact.id]);
+                listenerCB.oncontactsupdated([item2]);
+            });
+        },
+        updateBatch : function (contacts, successCB, errorCB) {
+            var inner = this, 
+                item, listenArray, item2;
+            function _updateBatch() {
+                var ret, i;
+                if (!_security.all && !_security.updateBatch) {
+                    throw new WebAPIError(errorcode.SECURITY_ERR);
+                }
+
+                if (!tizen1_utils.isValidArray(contacts)) {
+                    throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                } else {
+                    if (contacts.length === 0) {
+                        throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+                    }
+                    for (i = 0; i < contacts.length; i++) {
+                        if (_checkContactProperties(contacts[i], false) === false) {
+                            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+                        }
+                    }
+                }
+                if (inner.readOnly === true) {
+                    throw new WebAPIError(errorcode.SECURITY_ERR);
+                }
+
+                ret = _pendingOperate(function () {
+                    var i;
+                    for (i = 0; i < contacts.length; i++) {
+                        if (!contacts[i].id || !inner._contacts[contacts[i].id]) {
+                            if (errorCB) {
+                                errorCB(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                            }
+                            return;
+                        }
+                    }
+                    for (i = 0; i < contacts.length; i++) {
+                        item = new ContactPrivate(contacts[i], false);
+                        inner._contacts[item.id] = item;
+                    }
+                    _save();
+                    if (successCB) {
+                        successCB();
+                    }
+
+                    /* send changed notification */
+                    utils.forEach(inner._listeners, function (listenerCB) {
+                        listenArray = [];
+                        for (i = 0; i < contacts.length; i++) {
+                            item2 = new ContactPublic(inner._contacts[contacts[i].id]);
+                            listenArray.push(item2);
+                        }
+                        listenerCB.oncontactsupdated(listenArray);
+                    });
+                });
+                return;
+            }
+
+            _validateCallbackType(successCB, errorCB, _updateBatch);
+        },
+        remove : function (id) {
+            if (!_security.all && !_security.remove) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            if (typeof id !== "string") {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+
+            if (this.readOnly === true) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            if (this._contacts[id]) {
+                delete this._contacts[id];
+                _save();
+            } else {
+                throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+            }
+
+            /* send changed notification */
+            utils.forEach(this._listeners, function (listenerCB) {
+                listenerCB.oncontactsremoved([id]);
+            });
+        },
+        removeBatch : function (ids, successCB, errorCB) {
+            var inner = this;
+            function _removeBatch() {
+                var ret, i;
+                if (!_security.all && !_security.removeBatch) {
+                    throw new WebAPIError(errorcode.SECURITY_ERR);
+                }
+
+                if (!tizen1_utils.isValidArray(ids)) {
+                    throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                } else {
+                    if (ids.length === 0) {
+                        throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+                    }
+                    for (i = 0; i < ids.length; i++) {
+                        if (typeof ids[i] !== "string") {
+                            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                        }
+                    }
+                }
+
+                if (inner.readOnly === true) {
+                    throw new WebAPIError(errorcode.SECURITY_ERR);
+                }
+
+                ret = _pendingOperate(function () {
+                    var i;
+                    for (i = 0; i < ids.length; i++) {
+                        if (!inner._contacts[ids[i]]) {
+                            if (errorCB) {
+                                errorCB(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                            }
+                            return;
+                        }
+                    }
+                    for (i = 0; i < ids.length; i++) {
+                        if (inner._contacts[ids[i]]) {
+                            delete inner._contacts[ids[i]];
+                        }
+                    }
+                    _save();
+                    if (successCB) {
+                        successCB();
+                    }
+
+                    /* send changed notification */
+                    utils.forEach(inner._listeners, function (listenerCB) {
+                        listenerCB.oncontactsremoved(ids);
+                    });
+                });
+                return;
+            }
+
+            _validateCallbackType(successCB, errorCB, _removeBatch);
+        },
+        find : function (successCB, errorCB, filter, sortMode) {
+            var inner = this;
+
+            function _find() {
+                var result = [], result2 = [], begin, end, ret, i,
+                    atr, _re, errFlag = false, _rangeMatch, low, high, matched,
+                    _existMatch, _arrayMatch;
+
+                if (!_security.all && !_security.find) {
+                    throw new WebAPIError(errorcode.SECURITY_ERR);
+                }
+
+                if (filter) {
+                    switch (_filterType(filter)) {
+                    case 0:
+                        throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                    case 1:
+                        //TODO:
+                        //"compositeFilter doesn't support"
+                        throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
+                    case 2:
+                    case 3:
+                        break;
+                    }
+                }
+
+                /* return all contacts if no filter argument */
+                if (filter === null || filter === undefined) {
+                    utils.forEach(inner._contacts, function (contact) {
+                        result.push(new ContactPublic(contact));
+                    });
+                    ret = _pendingOperate(function () {
+                        successCB(result);
+                    });
+                    return ret;
+                }
+
+                /* check composition of filter.attributeName */
+                switch (filter.attributeName) {
+                case "id" :
+                case "name.prefix" :
+                case "name.firstName" :
+                case "name.middleName" :
+                case "name.lastName" :
+                case "name.phoneticName" :
+                case "name.displayName" :
+                case "account.accountServiceId" :
+                case "account.contactURI" :
+                case "photoURI" :
+                case "organization.name" :
+                case "organization.department" :
+                case "organization.office" :
+                case "organization.title" :
+                case "organization.role" :
+                case "organization.logoURI" :
+                case "ringtoneURI" :
+                    result = tizen1_utils.matchAttributeFilter(inner._contacts,
+                            filter.attributeName, filter.matchFlag, filter.matchValue);
+                    break;
+                case "name.nicknames" :
+                case "notes" :
+                case "categories" :
+                    result = tizen1_utils.matchAttributeArrayFilter(inner._contacts,
+                            filter.attributeName, filter.matchFlag, filter.matchValue);
+                    break;
+                case "addresses.country" :
+                case "addresses.region" :
+                case "addresses.city" :
+                case "addresses.streetAddress" :
+                case "addresses.additionalInformation" :
+                case "addresses.postalCode" :
+                case "phoneNumbers.number" :
+                case "emails.email" :
+                case "anniversaries.label" :
+                case "urls.url" :
+                case "urls.type" :
+                    atr = filter.attributeName.split(".");
+                    _existMatch = function (obj, index) {
+                        return (obj[atr[0]] !== undefined);
+                    };
+
+                    if (filter.matchValue === undefined || filter.matchFlag === "EXISTS") {
+                        result = utils.filter(inner._contacts, _existMatch);
+                        break;
+                    }
+
+                    errFlag = false;
+
+                    switch (filter.matchFlag)
+                    {
+                    case "EXACTLY":
+                        _re = new RegExp("^" + filter.matchValue + "$");
+                        break;
+                    case "FULLSTRING":
+                        _re = new RegExp("^" + filter.matchValue + "$", "i");
+                        break;
+                    case "CONTAINS":
+                        _re = new RegExp(filter.matchValue, "i");
+                        break;
+                    case "STARTSWITH":
+                        _re = new RegExp("^" + filter.matchValue, "i");
+                        break;
+                    case "ENDSWITH":
+                        _re = new RegExp(filter.matchValue + "$", "i");
+                        break;
+                    default:
+                        errFlag = true;
+                    }
+
+                    if (errFlag) {
+                        result = [];
+                        break;
+                    }
+
+                    _arrayMatch = function (obj, index) {
+                        return (obj[atr[0]].some(function (o) {
+                            if (typeof o[atr[1]] !== "string") {
+                                return false;
+                            } else {
+                                return (o[atr[1]].search(_re) !== -1);
+                            }
+                        }));
+                    };
+
+                    result = utils.filter(inner._contacts, _arrayMatch);
+                    break;
+                case "addresses.types" :
+                case "phoneNumbers.types" :
+                case "emails.types" :
+                    atr = filter.attributeName.split(".");
+                    _existMatch = function (obj, index) {
+                        return (obj[atr[0]].some(function (o) {
+                            return (o[atr[1]] !== undefined);
+                        }));
+                    };
+
+                    if (filter.matchValue === undefined || filter.matchFlag === "EXISTS") {
+                        result = utils.filter(inner._contacts, _existMatch);
+                        break;
+                    }
+
+                    errFlag = false;
+
+                    switch (filter.matchFlag)
+                    {
+                    case "EXACTLY":
+                        _re = new RegExp("^" + filter.matchValue + "$");
+                        break;
+                    case "FULLSTRING":
+                        _re = new RegExp("^" + filter.matchValue + "$", "i");
+                        break;
+                    case "CONTAINS":
+                        _re = new RegExp(filter.matchValue, "i");
+                        break;
+                    case "STARTSWITH":
+                        _re = new RegExp("^" + filter.matchValue, "i");
+                        break;
+                    case "ENDSWITH":
+                        _re = new RegExp(filter.matchValue + "$", "i");
+                        break;
+                    default:
+                        errFlag = true;
+                    }
+
+                    if (errFlag) {
+                        result = [];
+                        break;
+                    }
+
+                    _arrayMatch = function (obj, index) {
+                        return (obj[atr[0]].some(function (o) {
+                            if (!tizen1_utils.isValidArray(o[atr[1]])) {
+                                return false;
+                            } else {
+                                return (o[atr[1]].some(function (t) {
+                                    return (t.search(_re) !== -1);
+                                }));
+                            }
+                        }));
+                    };
+
+                    result = utils.filter(inner._contacts, _arrayMatch);
+                    break;
+                case "anniversaries.date" :
+                    low = filter.initialValue;
+                    high = filter.endValue;
+                    atr = filter.attributeName.split(".");
+
+                    if (low !== undefined && low !== null) {
+                        if (!tizen1_utils.isValidDate(low)) {
+                            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                        }
+                    }
+                    if (high !== undefined && high !== null) {
+                        if (!tizen1_utils.isValidDate(high)) {
+                            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                        }
+                    }
+
+                    _rangeMatch = function (obj, index) {
+                        matched = true;
+                        if (low !== null && low !== undefined) {
+                            if (!tizen1_utils.isValidArray(obj[atr[0]])) {
+                                matched = false;
+                            } else {
+                                matched = (obj[atr[0]].some(function (o) {
+                                    return (o[atr[1]] >= low);
+                                }));
+                            }
+                        }
+                        if (matched && (high !== null && high !== undefined)) {
+                            if (!tizen1_utils.isValidArray(obj[atr[0]])) {
+                                matched = false;
+                            } else {
+                                matched = (obj[atr[0]].some(function (o) {
+                                    return (o[atr[1]] <= high);
+                                }));
+                            }
+                        }
+                        return matched;
+                    };
+
+                    result = utils.filter(inner._contacts, _rangeMatch);
+                    break;
+                case "isFavorite" :
+                    if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
+                        throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                    } else {
+                        result = tizen1_utils.matchAttributeBooleanFilter(inner._contacts,
+                                filter.attributeName, filter.matchValue);
+                    }
+                    break;
+                case "birthday" :
+                    begin = filter.initialValue;
+                    end = filter.endValue;
+
+                    if (begin !== null && begin !== undefined) {
+                        if (!tizen1_utils.isValidDate(begin)) {
+                            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                        }
+                    }
+
+                    if (end !== null && end !== undefined) {
+                        if (!tizen1_utils.isValidDate(end)) {
+                            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                        }
+                    }
+                    
+                    result = tizen1_utils.matchAttributeRangeFilter(inner._contacts,
+                            filter.attributeName, begin, end);
+                    break;
+                default:
+                    throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+                }
+                ret = _pendingOperate(function () {
+                    for (i = 0; i < result.length; i++) {
+                        result2.push(new ContactPublic(result[i]));
+                    }
+                    successCB(result2);
+                });
+                return ret;
+            }
+
+            tizen1_utils.validateTypeMismatch(successCB, errorCB, "find", _find);
+        },
+        addChangeListener : function (successCB, errorCB) {
+            var inner = this,
+                id;
+
+            if (!_security.all && !_security.addChangeListener) {
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+            }
+
+            if (Object.prototype.toString.call(successCB) === "[object Object]") {
+                /* oncontactsadded, oncontactsupdated, oncontactsremoved all are not optional */
+                if (typeof successCB.oncontactsadded !== "function" ||
+                    typeof successCB.oncontactsupdated !== "function" ||
+                    typeof successCB.oncontactsremoved !== "function") {
+                    throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                }
+            } else {
+                /* AddressBookChangedCB is not a set of functions */
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+
+            if (errorCB) {
+                if (typeof errorCB !== "function") {
+                    throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+                }
+            }
+
+            id = ++inner._listenerCount;
+            inner._listeners[id] = successCB;
+            return id;
+        },
+        removeChangeListener : function (id) {
+            if (typeof id !== "number") {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            
+            if (this._listeners[id]) {
+                delete this._listeners[id];
+            }
+        }
+    };
+
+    addressBook.__defineGetter__("id", function () {
+        return id;
+    });
+
+    addressBook.__defineGetter__("name", function () {
+        return name;
+    });
+
+    addressBook.__defineGetter__("readOnly", function () {
+        return readOnly;
+    });
+
+    return addressBook;
+}
+
+function _get() {
+    var array = [],
+        data = db.retrieveObject(_KEY);
+
+    utils.forEach(data, function (addrBook) {
+        var i, j;
+        for (i in addrBook._contacts) {
+            if (addrBook._contacts[i].lastUpdated !== undefined &&
+                addrBook._contacts[i].lastUpdated !== null) {
+                addrBook._contacts[i].lastUpdated = new Date(addrBook._contacts[i].lastUpdated);
+            }
+            if (addrBook._contacts[i].birthday !== undefined &&
+                addrBook._contacts[i].birthday !== null) {
+                addrBook._contacts[i].birthday = new Date(addrBook._contacts[i].birthday);
+            }
+            if (addrBook._contacts[i].anniversaries &&
+                tizen1_utils.isValidArray(addrBook._contacts[i].anniversaries)) {
+                for (j = 0; j < addrBook._contacts[i].anniversaries.length; j++) {
+                    // Skip checking "date" exist or not due to it is mandatory 
+                    addrBook._contacts[i].anniversaries[j].date = new Date(addrBook._contacts[i].anniversaries[j].date);
+                }
+            }
+        }
+        array.push(new AddressBook(addrBook.id, addrBook.name, addrBook.readOnly, addrBook._contacts));
+    });
+
+    /* add default addressbook if database is empty */
+    if (array.length === 0) {
+        array = [new AddressBook(Math.uuid(undefined, 16), "Phone address book", false, {}), 
+                 new AddressBook(Math.uuid(undefined, 16), "SIM address book", false, {})];
+    }
+
+    return array;
+}
+
+function _save() {
+    db.saveObject(_KEY, _addressBooks);
+}
+
+_self = function () {
+    var contact = {
+        getAddressBooks: function (successCB, errorCB) {
+            function _getAddressBooks() {
+                if (_addressBooks.length === 0) {
+                    _addressBooks = _get();
+                }
+                successCB(_addressBooks);
+            }
+            tizen1_utils.validateTypeMismatch(successCB, errorCB, "getAddressBooks", _getAddressBooks);
+        },
+
+        getDefaultAddressBook: function () {
+            if (_addressBooks.length === 0) {
+                _addressBooks = _get();
+            }
+            return _addressBooks[0];
+        },
+
+        getAddressBook: function (id) {
+            var i;
+            if (typeof id !== "string") {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            if (_addressBooks.length === 0) {
+                _addressBooks = _get();
+            }
+            for (i = 0; i < _addressBooks.length; i++) {
+                if (_addressBooks[i].id === id) {
+                    return _addressBooks[i];
+                }
+            }
+
+            /* Cannot found */
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+        },
+
+        handleSubFeatures: function (subFeatures) {
+            var i, subFeature;
+            for (subFeature in subFeatures) {
+                if (_security[subFeature].length === 0) {
+                    _security.all = true;
+                    return;
+                }
+                _security.all = false;
+                for (i = 0; i < _security[subFeature].length; i++) {
+                    _security[_security[subFeature][i]] = true;
+                }
+            }
+        }
+    };
+
+    return contact;
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/AttributeRangeFilter', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+module.exports = function (_attributeName, _initialValue, _endValue) {
+    return {
+        attributeName: _attributeName,
+        initialValue: _initialValue,
+        endValue: _endValue
+    };
+};
+
+});
+require.define('ripple/platform/tizen/1.0/Notification', function (require, module, exports) {
+/*\r
+ *  Copyright 2012 Intel Corporation.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/*\r
+ * Parameters\r
+ * iconUrl\r
+ *    URL of the icon to be shown with this notification.\r
+ *    It supports full URL and relative URL from server access;\r
+ *    while only supports full URL beginning with "http://" from local file access.\r
+ * title\r
+ *    Primary text, or title, of the notification.\r
+ * body\r
+ *    Secondary text, or body, of the notification.\r
+ *\r
+ * Attributes\r
+ * onshow\r
+ *    An event listener function corresponding to the event type "show".\r
+ *    It replaced 'ondisplay' attribute of Chrome notifications.\r
+ */\r
+\r
+module.exports = function (iconUrl, title, body) {\r
+    var _self = window.webkitNotifications.createNotification(iconUrl, title, body);\r
+\r
+    _self.__defineSetter__("onshow", function (onshow) {\r
+        return _self.ondisplay = onshow;\r
+    });\r
+\r
+    return _self;\r
+};\r
+\r
+
+});
+require.define('ripple/platform/tizen/1.0/geocoder', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var SimpleCoordinates = require('ripple/platform/tizen/1.0/SimpleCoordinates'),
+    ProviderLocal = require('ripple/platform/tizen/1.0/geoBackend_local'),
+    ProviderNominatim = require('ripple/platform/tizen/1.0/geoBackend_nominatim'), // Nominatim geocode service
+    _getProviders,
+    _providers,
+    _self;
+
+function _initialize() {
+    _providers = [new ProviderNominatim({name : "Nominatim", connectivity : "ONLINE"})
+                  /* ,new ProviderLocal({name : "Tizen Database", connectivity : "OFFLINE"}) */];
+}
+
+_initialize();
+
+_self = {
+    getDefaultProvider : function () {
+        return _providers[0];
+    },
+    getProviders : function () {
+        return _providers;
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/systeminfo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    deviceSettings = require('ripple/deviceSettings'),
+    event = require('ripple/event'), 
+    tizen_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    _systemInfoProperties = ["Power", "Cpu", "Storage", "Display", "Device", "Network", "WifiNetwork", "CellularNetwork", "EthernetNetwork", "SIM"],
+    _propertyMap = {}, // Object like: {"Power": ["level", "isCharging"], ...}
+    _watches = {},
+    _powerData = {},
+    _self;
+
+function _asynchErrorCallback(errorCallback, errorCode) {
+    if (errorCallback) {
+        setTimeout(function () {
+            errorCallback(errorCode);
+        }, 1);
+    }
+}
+
+function _getValue(aspect, successCallback, errorCallback) {
+    var properties = [], value, index = 0, property, obj = {};
+
+    if (aspect === "Power") {
+        successCallback(utils.copy(_powerData));
+        return;
+    }
+
+    properties = _propertyMap[aspect];
+    for (; index < properties.length; index++) {
+        property = properties[index];
+
+        value = deviceSettings.retrieve(aspect + "." + property);
+        if (value === undefined || value === null) {
+
+            errorCallback(new WebAPIError(errorcode.SECURITY_ERR));
+            return null;
+        }
+
+        obj[property] = value;
+    }
+
+    successCallback(obj);
+}
+
+function _initialize() {
+    var aspectName, index, i;
+
+    for (index = 0; index < _systemInfoProperties.length; index++) {
+        aspectName = _systemInfoProperties[index];
+        _propertyMap[aspectName] = [];
+        for (i in deviceSettings.retrieve(aspectName)) {
+            _propertyMap[aspectName].push(i);
+        }
+    }
+
+    _propertyMap.Power.push("level");
+    _propertyMap.Power.push("isCharging");
+
+    event.on("BatteryEvent", function (status) {
+        _powerData.isCharging = status.charging;
+        _powerData.level = status.level;
+    });
+}
+
+function _isPropertyFound(propertyId) {
+    if (tizen_utils.isEmptyObject(_propertyMap)) {
+        _initialize();
+    }
+
+    if (_propertyMap[propertyId]) {
+        return true;
+    }
+
+    return false;
+}
+
+_self = {
+    isSupported: function (propertyId) {
+        return _isPropertyFound(propertyId);
+    },
+
+    getPropertyValue: function (propertyId, successCallback, errorCallback) {
+        return tizen_utils.validateTypeMismatch(successCallback, errorCallback, "getPropertyValue", function () {
+            if (_isPropertyFound(propertyId) === false) {
+                _asynchErrorCallback(errorCallback, new WebAPIError(errorcode.NOT_FOUND_ERR));
+                return undefined;
+            }
+
+            setTimeout(_getValue(propertyId, successCallback, errorCallback), 1); // Simulate a async operation
+
+            return null;
+        });
+    },
+
+    addPropertyValueChangeListener: function (propertyId, successCallback, errorCallback, options) {  
+        return tizen_utils.validateTypeMismatch(successCallback, errorCallback, "addPropertyValueChangeListener", function () {
+            if (_isPropertyFound(propertyId) === false) {
+                _asynchErrorCallback(errorCallback, new WebAPIError(errorcode.NOT_FOUND_ERR));
+                return undefined;
+            }
+
+            var watchId = (new Date()).getTime() | 0,
+                _options = Object(options),
+                properties, property, index = 0, deviceEventType, watchObj;
+
+            // A listener will listen all the properties of one aspect, each of the property
+            // will have an internal watchObj to record the information.
+            _watches[watchId] = [];
+
+            // Immediately returns and then asynchronously starts a watch ...
+            setTimeout(function () {
+                _getValue(propertyId, successCallback, errorCallback);
+
+                properties = _propertyMap[propertyId];
+                
+                for (; index < properties.length; index++) {
+                    property = properties[index];
+                    if (propertyId === "Power") {
+                        deviceEventType = "BatteryEvent";
+                    }
+                    else {
+                        deviceEventType = deviceSettings.retrieve(propertyId)[property].event;
+                    }
+
+                    // These two items are needed when delete an event listener.
+                    watchObj = {
+                        eventType: deviceEventType,
+                        onEvent: function (newValue) {
+                            if (watchObj.timeout) {
+                                clearInterval(watchObj.intervalId);
+                                watchObj.intervalId = setInterval(function () {
+                                    _getValue(propertyId, successCallback, errorCallback);
+                                }, watchObj.timeout);
+                            }
+
+                            if ((watchObj.highThreshold && (newValue < watchObj.highThreshold)) ||
+                                (watchObj.lowThreshold && (newValue > watchObj.lowThreshold))) {
+                                return;
+                            }
+
+                            _getValue(propertyId, successCallback, errorCallback);
+                        }
+                    };
+
+                    if (options && _options.timeout) {
+                        watchObj.intervalId = setInterval(function () {
+                            _getValue(propertyId, successCallback, errorCallback);
+                        }, _options.timeout);
+                    }
+
+                    if (options && _options.highThreshold) {
+                        watchObj.highThreshold = _options.highThreshold;
+                    }
+
+                    if (options && _options.lowThreshold) {
+                        watchObj.lowThreshold = _options.lowThreshold;
+                    }
+                
+                    _watches[watchId].push(watchObj);
+                    if (watchObj.eventType) {
+                        event.on(watchObj.eventType, watchObj.onEvent);
+                    }
+                }
+
+            }, 1);
+
+            return watchId;
+        });
+    },
+
+    removePropertyChangeListener: function (listenerID) {
+        var _handler = listenerID | 0, index = 0, watchObjs = [], watchObj;
+
+        watchObjs = _watches[_handler];
+        if (watchObjs) {
+            for (; index < watchObjs.length; index++) {
+                watchObj = watchObjs[index];
+                event.deleteEventHandler(watchObj.eventType, watchObj.onEvent);
+                if (watchObj.intervalId) {
+                    clearInterval(watchObj.intervalId);
+                }
+            }
+            delete(_watches[_handler]);
+        }
+        return null;
+    }
+};
+
+module.exports = _self;
+
+
+});
+require.define('ripple/platform/tizen/1.0/ContactBase', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+var tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    ContactName = require('ripple/platform/tizen/1.0/ContactName'),
+    ContactOrganization = require('ripple/platform/tizen/1.0/ContactOrganization'),
+    ContactWebSite = require('ripple/platform/tizen/1.0/ContactWebSite'),
+    ContactAnniversary = require('ripple/platform/tizen/1.0/ContactAnniversary'),
+    ContactAccount = require('ripple/platform/tizen/1.0/ContactAccount'),
+    ContactAddress = require('ripple/platform/tizen/1.0/ContactAddress'),
+    ContactPhoneNumber = require('ripple/platform/tizen/1.0/ContactPhoneNumber'),
+    ContactEmailAddress = require('ripple/platform/tizen/1.0/ContactEmailAddress');
+
+function _clone(obj) {
+    var copy = obj.constructor(), attr;
+    for (attr in obj) {
+        if (obj.hasOwnProperty(attr))
+            copy[attr] = obj[attr];
+    }
+    /* remove these two attribute */
+    copy.id = null;
+    copy.lastUpdated = null;
+    return copy;
+}
+
+module.exports = function (prop) {
+    var _self, i;
+    _self = {
+        id : null,
+        lastUpdated : null,
+        name : null,
+        account : null,
+        addresses : [],
+        photoURI : null,
+        phoneNumbers : undefined,
+        emails : undefined,
+        birthday : null,
+        anniversaries : null,
+        organization : null,
+        notes : [],
+        urls : [],
+        isFavorite : false,
+        ringtoneURI : null,
+        categories : [],
+        convertToString : function (format) {
+            //TODO
+            console.log("convert to VCard String...");
+        },
+        clone : function () {
+            return _clone(this);
+        },
+    };
+    
+    if (prop) {
+        /* id: (readonly)
+        By default, this attribute is set to null.
+        This attribute will be generated when adding to the AddressBook */
+
+        /* lastUpdated: (readonly)
+        By default, this attribute is set to null.
+        This attribute will be generated when adding to the AddressBook */
+
+        if (prop.name) {
+            _self.name = new ContactName(prop.name);
+        }
+        if (prop.account) {
+            _self.account = new ContactAccount(prop.account.accountServiceId, prop.account.contactURI);
+        }
+        if (tizen1_utils.isValidArray(prop.addresses)) {
+            for (i = 0; i < prop.addresses.length; i++) {
+                _self.addresses.push(new ContactAddress(prop.addresses[i]));
+            }
+        }
+        if (prop.photoURI) {
+            _self.photoURI = String(prop.photoURI);
+        }
+        if (tizen1_utils.isValidArray(prop.phoneNumbers)) {
+            _self.phoneNumbers = [];
+            for (i = 0; i < prop.phoneNumbers.length; i++) {
+                _self.phoneNumbers.push(new ContactPhoneNumber(
+                            prop.phoneNumbers[i].number, prop.phoneNumbers[i].types));
+            }
+        }
+        if (tizen1_utils.isValidArray(prop.emails)) {
+            _self.emails = [];
+            for (i = 0; i < prop.emails.length; i++) {
+                _self.emails.push(new ContactEmailAddress(
+                            prop.emails[i].email, prop.emails[i].types));
+            }
+        }
+        if (tizen1_utils.isValidDate(prop.birthday)) {
+            _self.birthday = new Date(prop.birthday);
+        }
+        if (tizen1_utils.isValidArray(prop.anniversaries)) {
+            _self.anniversaries = [];
+            for (i = 0; i < prop.anniversaries.length; i++) {
+                _self.anniversaries.push(new ContactAnniversary(
+                            prop.anniversaries[i].date, prop.anniversaries[i].label));
+            }
+        }
+        if (prop.organization) {
+            _self.organization = new ContactOrganization(prop.organization);
+        }
+        if (tizen1_utils.isValidArray(prop.notes)) {
+            for (i = 0; i < prop.notes.length; i++) {
+                _self.notes.push(String(prop.notes[i]));
+            }
+        }
+        if (tizen1_utils.isValidArray(prop.urls)) {
+            for (i = 0; i < prop.urls.length; i++) {
+                _self.urls.push(new ContactWebSite(
+                            prop.urls[i].url, prop.urls[i].type));
+            }
+        }
+        if (typeof prop.isFavorite === "boolean") {
+            _self.isFavorite = prop.isFavorite;
+        }
+        if (prop.ringtoneURI) {
+            _self.ringtoneURI = String(prop.ringtoneURI);
+        }
+        if (tizen1_utils.isValidArray(prop.categories)) {
+            for (i = 0; i < prop.categories.length; i++) {
+                _self.categories.push(String(prop.categories[i]));
+            }
+        }
+    }
+    
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/Conversation', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils');
+
+module.exports = function (opt) {
+    var conv = {}, priv = utils.copy(opt);
+
+    conv.__defineGetter__("id", function () {
+        return priv.id;
+    });
+    conv.__defineGetter__("type", function () {
+        return priv.type;
+    });
+    conv.__defineGetter__("timestamp", function () {
+        return priv.timestamp;
+    });
+    conv.__defineGetter__("messageCount", function () {
+        return priv.messageCount;
+    });
+    conv.__defineGetter__("unreadMessages", function () {
+        return priv.unreadMessages;
+    });
+    conv.__defineGetter__("preview", function () {
+        return priv.preview;
+    });
+    conv.__defineGetter__("subject", function () {
+        return priv.subject;
+    });
+    conv.__defineGetter__("isRead", function () {
+        return priv.isRead;
+    });
+    conv.__defineGetter__("from", function () {
+        return priv.from;
+    });
+    conv.__defineGetter__("to", function () {
+        return priv.to;
+    });
+    conv.__defineGetter__("cc", function () {
+        return priv.cc;
+    });
+    conv.__defineGetter__("bcc", function () {
+        return priv.bcc;
+    });
+    conv.__defineGetter__("lastMessageId", function () {
+        return priv.lastMessageId;
+    });
+    return conv;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/GeoRectBounds', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (_southWest, _northEast) {
+    var southWest, northEast;
+    southWest = _southWest || null;
+    northEast = _northEast || null;
+
+    this.__defineGetter__("southWest", function () {
+        return southWest;
+    });
+
+    this.__defineGetter__("northEast", function () {
+        return northEast;
+    });
+};
+
+});
+require.define('ripple/platform/tizen/1.0/PowerStateRequest', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (resource, state) {
+    var _self,
+        _state = state || null,
+        _resource = resource || null;
+
+    _self = {
+        resource : _resource,
+        minimalState : _state
+    };
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/EventBase', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function () {
+    var _self = {
+        CAPTURING_PHASE: 1,
+        AT_TARGET:  2,
+        BUBBLING_PHASE: 3,
+
+        type: '',
+        target: null, //new EventTarget(),
+        currentTarget: null, //new EventTarget(),
+        eventPhase: 0,
+        bubbles: false,
+        cancelable: false,
+        timeStamp: 0
+    };
+
+    this.__defineGetter__("type", function () {
+        return _self.type;
+    });
+
+    this.__defineGetter__("target", function () {
+        return _self.target;
+    });
+
+    this.__defineGetter__("currentTarget", function () {
+        return _self.currentTarget;
+    });
+
+    this.__defineGetter__("eventPhase", function () {
+        return _self.eventPhase;
+    });
+
+    this.__defineGetter__("bubbles", function () {
+        return _self.bubbles;
+    });
+
+    this.__defineGetter__("cancelable", function () {
+        return _self.cancelable;
+    });
+
+    this.__defineGetter__("timeStamp", function () {
+        return _self.timeStamp;
+    });
+
+    this.stopPropagation = function () {};
+
+    this.preventDefault = function () {};
+
+    this.initEvent = function (eventTypeArg, canBubbleArg, cancelableArg) {
+        _self.type = eventTypeArg;
+        _self.bubbles = canBubbleArg;
+        _self.cancelable = cancelableArg;
+
+        _self.timeStamp = (new Date()).getTime();
+    };
+
+    return _self;
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/ContactRef', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+var tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError');
+
+module.exports = function (addressBookId, contactId) {
+    var _self, _addressBookId,
+        _contactId;
+    
+    if (typeof addressBookId !== "string") {
+        throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+    }
+
+    if (typeof contactId !== "string") {
+        throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+    }
+
+    _self = {
+        addressBookId : _addressBookId,
+        contactId : _contactId
+    };
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/timezone_info', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var _self,
+    _timezone_data = {
+    "International Date Line West": {diff: -12, abbr: ""},
+    "Coordinated Universal Time-11": {diff: -11, abbr: ""},
+    "Samoa": {diff: -11, abbr: ""},
+    "Hawaii": {diff: -10, abbr: ""},
+    "Alaska": {diff: -9, abbr: ""},
+    "Baja California": {diff: -8, abbr: ""},
+    "Pacific Time (US & Canada)": {diff: -8, abbr: ""},
+    "Arizona": {diff: -7, abbr: ""},
+    "Chihuahua, La Paz, Mazatlan": {diff: -7, abbr: ""},
+    "Mountain Time (US & Canada)": {diff: -7, abbr: ""},
+    "Central America": {diff: -6, abbr: ""},
+    "Central Time (US & Canada)": {diff: -6, abbr: ""},
+    "Guadalajara, Mexico City, Monterrey": {diff: -6, abbr: ""},
+    "Saskatchewan": {diff: -6, abbr: ""},
+    "Bogota, Lima, Quito": {diff: -5, abbr: ""},
+    "Eastern Time (US & Canada)": {diff: -5, abbr: ""},
+    "Indiana (East)": {diff: -5, abbr: ""},
+//    "Caracas": {diff: -4.5, abbr: ""},
+    "Asuncion": {diff: -4, abbr: ""},
+    "Atlantic Time (Canada)": {diff: -4, abbr: ""},
+    "Cuiaba": {diff: -4, abbr: ""},
+    "Georgetown, La Paz, Manaus, San Juan": {diff: -4, abbr: ""},
+    "Santiago": {diff: -4, abbr: ""},
+//    "Newfoundland": {diff: -3.5, abbr: ""},
+    "Brasilia": {diff: -3, abbr: ""},
+    "Buenos Aires": {diff: -3, abbr: "ART"},
+    "Cayenne, Fortaleza": {diff: -3, abbr: ""},
+    "Greenland": {diff: -3, abbr: ""},
+    "Montevideo": {diff: -3, abbr: ""},
+    "Coordinated Universal Time-02": {diff: -2, abbr: ""},
+    "Mid-Atlantic": {diff: -2, abbr: ""},
+    "Azores": {diff: -1, abbr: ""},
+    "Cape Verde Is.": {diff: -1, abbr: ""},
+    "Casablanca": {diff: 0, abbr: "UTC"},
+    "Coordinated Universal Time": {diff: 0, abbr: "UTC"},
+    "Dublin, Edinburgh, Lisbon, London": {diff: 0, abbr: "UTC"},
+    "Monrovia, Reykjavik": {diff: 0, abbr: "UTC"},
+    "Amsterdam, Berlin, Bern": {diff: 1, abbr: ""},
+    "Rome, Stockholm, Vienna": {diff: 1, abbr: ""},
+    "Belgrade, Bratislava, Budapest": {diff: 1, abbr: ""},
+    "Ljubljana, Prague": {diff: 1, abbr: ""},
+    "Brussels, Copenhagen, Madrid, Paris": {diff: 1, abbr: "CET"},
+    "Sarajevo, Skopje, Warsaw, Zagreb": {diff: 1, abbr: ""},
+    "West Central Africa": {diff: 1, abbr: ""},
+    "Windhoek": {diff: 1, abbr: ""},
+    "Amman": {diff: 2, abbr: ""},
+    "Athens, Bucharest": {diff: 2, abbr: "EET"},
+    "Beirut": {diff: 2, abbr: ""},
+    "Cairo": {diff: 2, abbr: "EET"},
+    "Damascus": {diff: 2, abbr: ""},
+    "Harare, Pretoria": {diff: 2, abbr: ""},
+    "Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius": {diff: 2, abbr: ""},
+    "Istanbul": {diff: 2, abbr: ""},
+    "Jerusalem": {diff: 2, abbr: ""},
+    "Minsk": {diff: 2, abbr: ""},
+    "Baghdad": {diff: 3, abbr: ""},
+    "Kaliningrad": {diff: 3, abbr: ""},
+    "Kuwait, Riyadh": {diff: 3, abbr: ""},
+    "Nairobi": {diff: 3, abbr: ""},
+//    "Tehran": {diff: 3.5, abbr: ""},
+    "Abu Dhabi, Muscat": {diff: 4, abbr: ""},
+    "Baku": {diff: 4, abbr: ""},
+    "Moscow, St. Petersburg, Volgograd": {diff: 4, abbr: ""},
+    "Port Louis": {diff: 4, abbr: ""},
+    "Tbilisi": {diff: 4, abbr: ""},
+    "Yerevan": {diff: 4, abbr: ""},
+//    "Kabul": {diff: 4.5, abbr: ""},
+    "Islamabad, Karachi": {diff: 5, abbr: ""},
+    "Tashkent": {diff: 5, abbr: ""},
+//    "Chennai, Kolkata, Mumbai, New Delhi": {diff: 5.5, abbr: ""},
+//    "Sri Jayawardenepura": {diff: 5.5, abbr: ""},
+//    "Kathmandu": {diff: 5.75, abbr: ""},
+    "Astana": {diff: 6, abbr: ""},
+    "Dhaka": {diff: 6, abbr: ""},
+    "Ekaterinburg": {diff: 6, abbr: ""},
+//    "Yangon (Rangoon)": {diff: 6.5, abbr: ""},
+    "Bangkok, Hanoi, Jakarta": {diff: 7, abbr: ""},
+    "Novosibirsk": {diff: 7, abbr: ""},
+    "Beijing, Chongqing, Hong Kong, Urumqi": {diff: 8, abbr: "CST"},
+    "Krasnoyarsk": {diff: 8, abbr: ""},
+    "Kuala Lumpur, Singapore": {diff: 8, abbr: "SGT"},
+    "Perth": {diff: 8, abbr: ""},
+    "Taipei": {diff: 8, abbr: ""},
+    "Ulaanbaatar": {diff: 8, abbr: ""},
+    "Irkutsk": {diff: 9, abbr: ""},
+    "Osaka, Sapporo, Tokyo": {diff: 9, abbr: "JST"},
+    "Seoul": {diff: 9, abbr: "KST"},
+//    "Adelaide": {diff: 9.5, abbr: ""},
+//    "Darwin": {diff: 9.5, abbr: ""},
+    "Brisbane": {diff: 10, abbr: ""},
+    "Canberra, Melbourne, Sydney": {diff: 10, abbr: "EST"},
+    "Guam, Port Moresby": {diff: 10, abbr: ""},
+    "Hobart": {diff: 10, abbr: ""},
+    "Yakutsk": {diff: 10, abbr: ""},
+    "Solomon Is., New Caledonia": {diff: 11, abbr: ""},
+    "Vladivostok": {diff: 11, abbr: ""},
+    "Auckland, Wellington": {diff: 12, abbr: ""},
+    "Coordinated Universal Time+12": {diff: 12, abbr: ""},
+    "Fiji": {diff: 12, abbr: ""},
+    "Magadan": {diff: 12, abbr: ""},
+    "Nuku'alofa": {diff: 13, abbr: ""}
+};
+
+module.exports = {
+    getAllTimezone: function () {
+        var i, ret = [];
+        for (i in _timezone_data)
+            ret.push(i);
+        return ret;
+    },
+    getTimezoneDiff: function (zone) {
+        return _timezone_data[zone].diff;
+    },
+    getTimezoneAbbr: function (zone) {
+        return _timezone_data[zone].abbr;
+    },
+    isValidTimezone: function (zone) {
+        return (_timezone_data[zone] === undefined) ? false : true;
+    }
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/bluetooth', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    event = require('ripple/event'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    PendingObject = require('ripple/platform/tizen/1.0/pendingObject'),
+    PendingOperation = require('ripple/platform/tizen/1.0/pendingoperation'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    BluetoothClass,
+    BluetoothClassDeviceMajor,
+    BluetoothClassDeviceMinor,
+    BluetoothClassDeviceService,
+    BluetoothServiceHandler,
+    BluetoothDevice,
+    BluetoothSocket,
+    BluetoothAdapter,
+    _data = {
+        DB_BLUETOOTH_KEY : "tizen1-db-bluetooth_adapter",
+        DB_BLUETOOTH_LOC_SERVICES_KEY : "tizen1-db-bluetooth_loc_services",
+        DB_BLUETOOTH_HISTORY_DEVICES_KEY : "tizen1-db-bluetooth_history_devices",
+        SERVICE_UUID : "5bce9431-6c75-32ab-afe0-2ec108a30860",
+        DEFAULT_VISIBLE_TIME : 180000,
+        DISCOVER_TIME : 20000,
+        DISCOVER_INTERVAL : 2000,
+        BOND_INTERVAL : 2000,
+        bluetoothClassDeviceMajor : {},
+        bluetoothClassDeviceMinor : {},
+        bluetoothClassDeviceService : {},
+        regCallback : null,
+        bondDevice : {},
+        adapter : {},
+        historyDevs : [],
+        locServices : [],
+        serviceName : "",
+        remote : {
+            pairedDevice : {},
+            sentData : "",
+            devices : [],
+            bondStatus : "",
+            isAway : false
+        }
+    },
+    _security = {
+        "http://tizen.org/api/bluetooth": [],
+        "http://tizen.org/api/bluetooth.admin": ["setName", "setPowered", "setVisible"],
+        "http://tizen.org/api/bluetooth.gap": ["discoverDevices", "stopDiscovery", "getKnownDevices", "getDevice", "createBonding", "destroyBonding"],
+        "http://tizen.org/api/bluetooth.spp": ["registerRFCOMMServiceByUUID", "connectToServiceByUUID", "unregister", "writeData", "readData", "close"],
+        all: true
+    },
+    _self;
+
+function _defaultAdapter() {
+    var adapter = {
+        name : "TU722",
+        address : "00:00:00:00:00:00",
+        powered : false,
+        visible : false
+    };
+    return adapter;
+}
+
+// Get the local adapter
+function _get() {
+    return db.retrieveObject(_data.DB_BLUETOOTH_KEY) || _defaultAdapter();
+}
+
+// Save the information of the local adapter
+function _save(name, address, powered, visible) {
+    var adapterDev = {
+        name : name,
+        address : address,
+        powered : powered,
+        visible : visible
+    };
+    db.saveObject(_data.DB_BLUETOOTH_KEY, adapterDev);
+}
+
+// Initialize the local adapter and the remote device, the remote service
+function _initialize() {
+    var adapterDev;
+
+    event.trigger("deviceInit", [_data.remote]);
+
+    _data.bluetoothClassDeviceMajor = new BluetoothClassDeviceMajor();
+    _data.bluetoothClassDeviceMinor = new BluetoothClassDeviceMinor();
+    _data.bluetoothClassDeviceService = new BluetoothClassDeviceService();
+
+    _data.locServices = db.retrieveObject(_data.DB_BLUETOOTH_LOC_SERVICES_KEY) || [];
+    _data.historyDevs = db.retrieveObject(_data.DB_BLUETOOTH_HISTORY_DEVICES_KEY) || [];
+
+    adapterDev = _get();
+    _data.adapter = new BluetoothAdapter(adapterDev.name, adapterDev.address, adapterDev.powered, adapterDev.visible);
+}
+
+function _getDevice(device) {
+    var bc, bd;
+    bc = new BluetoothClass(device.deviceClass.major, device.deviceClass.minor, device.deviceClass.services);
+    bd = new BluetoothDevice(device.name, device.address, bc, device.isBonded, device.isTrusted, device.isConnected, device.uuids);
+    return bd;
+}
+
+// Validate the callback type
+function _validateCallbackType(onSuccess, onError) {
+    if (onSuccess &&
+        (typeof onSuccess !== "function") &&
+        (typeof onSuccess !== "object")) {
+        throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+    }
+    if (onError) {
+        tizen1_utils.validateArgumentType(onError, "function",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+    }
+    if (onSuccess.onstarted) {
+        tizen1_utils.validateArgumentType(onSuccess.onstarted, "function",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+    }
+    if (onSuccess.ondevicefound) {
+        tizen1_utils.validateArgumentType(onSuccess.ondevicefound, "function",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+    }
+    if (onSuccess.ondevicedisappeared) {
+        tizen1_utils.validateArgumentType(onSuccess.ondevicedisappeared, "function",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+    }
+    if (onSuccess.onfinished) {
+        tizen1_utils.validateArgumentType(onSuccess.onfinished, "function",
+            new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+    }
+}
+
+function _stringToBytes(str) {
+    var ch, st, re = [], i;
+
+    for (i = 0; i < str.length; i++) {
+        ch = str.charCodeAt(i);
+        st = [];
+        do {
+            st.push(ch & 0xFF);
+            ch = ch >> 8;
+        } while (ch);
+        re = re.concat(st.reverse());
+    }
+
+    return re;
+}
+
+// Define the BluetoothAdapter
+BluetoothAdapter = function (devName, devAddress, devPowered, devVisible) {
+    var adapter,
+        isStopFound = false,
+        _devName = devName,
+        _devAddress = devAddress,
+        _devPowered = devPowered,
+        _devVisible = devVisible;
+
+    // Set the adapter name
+    function setName(name, successCallback, errorCallback) {
+        if (!_security.all && !_security.setName)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        if (typeof name !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (!_devPowered || name === "") {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+        _devName = name;
+        _save(_devName, _devAddress, _devPowered, _devVisible);
+        successCallback();
+    }
+
+    // Set the adapter power
+    function setPowered(state, successCallback, errorCallback) {
+        if (!_security.all && !_security.setPowered)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        if (typeof state !== "boolean")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        _devPowered = state;
+        _save(_devName, _devAddress, _devPowered, _devVisible);
+        successCallback();
+    }
+
+    // Set the adapter visible or invisible
+    function setVisible(mode, successCallback, errorCallback, timeout) {
+        var time;
+
+        if (!_security.all && !_security.setVisible)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        if (typeof mode !== "boolean" || (timeout && (typeof timeout !== "number")))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (!_devPowered) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+
+        _devVisible = mode;
+        time = timeout || _data.DEFAULT_VISIBLE_TIME;
+        _save(_devName, _devAddress, _devPowered, _devVisible);
+        if (mode && (time !== 0)) {
+            // Set timeout operate
+            setTimeout(function () {
+                _devVisible = false;
+                _save(_devName, _devAddress, _devPowered, _devVisible);
+            }, time);
+        }
+        successCallback();
+    }
+
+    // Discover the information of the found devices
+    function discoverDevices(successCallback, errorCallback) {
+        var interval, remoteDev, count, num = 0, isExisted,
+            remoteAddress = _data.remote.pairedDevice.address;
+
+        if (!_security.all && !_security.discoverDevices)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        _validateCallbackType(successCallback, errorCallback);
+
+        if (!_devPowered) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+        // Clear the data other than the pairing
+        for (count in _data.historyDevs) {
+            if (!_data.historyDevs[count].isBonded) {
+                _data.historyDevs.splice(count, 1);
+            }
+        }
+        successCallback.onstarted();
+        isStopFound = false;
+        // Discover process
+        interval = setInterval(function () {
+            if (isStopFound || num === _data.remote.devices.length) {
+                clearInterval(interval);
+                return;
+            }
+            if (_data.remote.isAway && remoteAddress) {
+                successCallback.ondevicedisappeared(_data.remote.pairedDevice.address);
+                remoteAddress = null;
+            }
+            remoteDev = _data.remote.devices[num];
+            successCallback.ondevicefound(remoteDev);
+            isExisted = false;
+            for (var i in _data.historyDevs) {
+                if (_data.historyDevs[i].address === remoteDev.address) {
+                    isExisted = true;
+                    break;
+                }
+            }
+            if (!isExisted) {
+                _data.historyDevs.push(remoteDev);
+            }
+            db.saveObject(_data.DB_BLUETOOTH_HISTORY_DEVICES_KEY, _data.historyDevs);
+            num++;
+        }, _data.DISCOVER_INTERVAL);
+        setTimeout(function () {
+            successCallback.onfinished(_data.historyDevs);
+            clearInterval(interval);
+        }, _data.DISCOVER_TIME);
+    }
+
+    // Stop discovering the information of the found devices
+    function stopDiscovery(successCallback, errorCallback) {
+        if (!_security.all && !_security.stopDiscovery)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        if (!_devPowered) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+        isStopFound = true;
+        successCallback();
+    }
+
+    // Get known devices which are connected
+    function getKnownDevices(successCallback, errorCallback) {
+        var knownDevs = _data.historyDevs;
+
+        if (!_security.all && !_security.getKnownDevices)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        _validateCallbackType(successCallback, errorCallback);
+
+        if (!_devPowered || !knownDevs) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+        successCallback(knownDevs);
+    }
+
+    // Get the information of the device
+    function getDevice(address, successCallback, errorCallback) {
+        var _address = [];
+
+        if (!_security.all && !_security.getDevice)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        if (typeof address !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        _validateCallbackType(successCallback, errorCallback);
+
+        if (!_devPowered) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+        utils.forEach(_data.historyDevs, function (item, index) {
+            if (item.address === address) {
+                successCallback(item);
+            }
+        });
+    }
+
+    // Bonding the local device and remote device
+    function createBonding(address, successCallback, errorCallback) {
+        var pendingObj, index, intervalKey, adapterDev, pendingOperation, item;
+
+        if (!_security.all && !_security.createBonding)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        if (typeof address !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        _validateCallbackType(successCallback, errorCallback);
+
+        if (!_devPowered || _data.historyDevs === undefined) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+        _data.remote.bondStatus = "";
+        utils.forEach(_data.historyDevs, function (item, index) {
+            if (item.address === address) {
+                adapterDev = _get();
+                pendingObj = new PendingObject();
+                pendingObj.pendingID = setTimeout(function () {
+                    pendingObj.setCancelFlag(false);
+                    if (!item.isBonded) {
+                        event.trigger("bondingCreated", [adapterDev.name]);
+                        intervalKey = setInterval(function () {
+                            if (_data.remote.bondStatus) {
+                                clearInterval(intervalKey);
+                            }
+                            if (_data.remote.bondStatus === "bonding") {
+                                event.trigger("bondingSucceeded", []);
+                                _data.historyDevs[index].isBonded = true;
+                                db.saveObject(_data.DB_BLUETOOTH_HISTORY_DEVICES_KEY, _data.historyDevs);
+                                _data.bondDevice = _getDevice(_data.historyDevs[index]);
+                                successCallback(_data.bondDevice);
+                            } else if (_data.remote.bondStatus === "noBonding") {
+                                errorCallback();
+                            }
+                        }, _data.BOND_INTERVAL);
+                    }
+                }, 1);
+                pendingOperation = new PendingOperation(pendingObj);
+            }
+        });
+        return pendingOperation;
+    }
+
+    // Destroy bonding from the local device and remote device
+    function destroyBonding(address, successCallback, errorCallback) {
+        var index;
+
+        if (!_security.all && !_security.destroyBonding)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        if (typeof address !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+        if (!_devPowered || _data.historyDevs === undefined) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+        for (index in _data.historyDevs) {
+            if (_data.historyDevs[index].address === address) {
+                if (_data.historyDevs[index].isBonded) {
+                    _data.historyDevs[index].isBonded = false;
+                }
+            }
+        }
+        db.saveObject(_data.DB_BLUETOOTH_HISTORY_DEVICES_KEY, _data.historyDevs);
+        _data.bondDevice = {};
+        event.trigger("bondingDestroyed", []);
+        successCallback();
+    }
+
+    // Register service by UUID
+    function registerRFCOMMServiceByUUID(uuid, name, successCallback, errorCallback, securityLevel) {
+        var locService, count, isExisted = false;
+
+        if (!_security.all && !_security.registerRFCOMMServiceByUUID)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        if (typeof name !== "string" || typeof uuid !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        _validateCallbackType(successCallback, errorCallback);
+
+        if (typeof name !== "string" || typeof uuid !== "string")
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (!_devPowered) {
+            if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+            return;
+        }
+
+        locService = {serviceInfo: {uuid: uuid, name: name}};
+        for (count in _data.locServices) {
+            if (_data.locServices[count].name === locService.name) {
+                isExisted = true;
+                break;
+            }
+        }
+        if (!isExisted) {
+            _data.locServices.push(locService);
+        }
+        db.saveObject(_data.DB_BLUETOOTH_LOC_SERVICES_KEY, _data.locServices);
+        _data.regCallback = successCallback;
+        _data.serviceName = name;
+    }
+
+    event.on("remoteDevAway", function (isAway) {
+        _data.remote.isAway = true;
+    });
+
+    event.on("remoteDevBonded", function (status) { // AcceptConnect
+        _data.remote.bondStatus = status;
+    });
+
+    event.on("remoteDevDetached", function (address) {
+        destroyBonding(address, function () {}, function () {});
+    });
+
+    adapter = {
+        setName : setName,
+        setPowered : setPowered,
+        setVisible : setVisible,
+        discoverDevices : discoverDevices,
+        stopDiscovery : stopDiscovery,
+        getKnownDevices : getKnownDevices,
+        getDevice : getDevice,
+        createBonding : createBonding,
+        destroyBonding : destroyBonding,
+        registerRFCOMMServiceByUUID : registerRFCOMMServiceByUUID
+    };
+
+    adapter.__defineGetter__("name", function () {
+        return _devName;
+    });
+    adapter.__defineGetter__("address", function () {
+        return _devAddress;
+    });
+    adapter.__defineGetter__("powered", function () {
+        return _devPowered;
+    });
+    adapter.__defineGetter__("visible", function () {
+        return _devVisible;
+    });
+
+    return adapter;
+};
+
+event.on("remoteDataArrived", function (remoteData) {
+    var index, bluetoothSocket, bluetoothServiceHandler;
+
+    _data.remote.sentData = remoteData;
+    if (!_data.regCallback || _data.remote.bondStatus !== "bonding") {
+        return;
+    }
+
+    for (index in _data.locServices) {
+        if (_data.locServices[index].serviceInfo.name === _data.serviceName) {
+            bluetoothSocket = new BluetoothSocket(_data.SERVICE_UUID, "RFCOMM", "OPEN", _data.bondDevice);
+            bluetoothServiceHandler = new BluetoothServiceHandler(_data.locServices[index].serviceInfo.uuid, _data.locServices[index].serviceInfo.name, true);
+            _data.regCallback(bluetoothServiceHandler);
+            break;
+        }
+    }
+
+    if (bluetoothServiceHandler.onconnect === null)
+        return;
+
+    if (typeof bluetoothServiceHandler.onconnect !== "function")
+        throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+    bluetoothServiceHandler.onconnect(bluetoothSocket);
+
+    if (bluetoothSocket.onmessage === null)
+        return;
+
+    if (typeof bluetoothSocket.onmessage !== "function")
+        throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+    bluetoothSocket.onmessage();
+});
+
+// The BluetoothDevice object
+BluetoothDevice = function (name, address, deviceClass, isBonded, isTrusted, isConnected, uuids) {
+    var bluetoothSocket, socketInfo,
+        _name = tizen1_utils.copyString(name),
+        _address = tizen1_utils.copyString(address),
+        _deviceClass = tizen1_utils.copyString(deviceClass),
+        _isBonded = isBonded,
+        _isTrusted = isTrusted,
+        _isConnected = isConnected,
+        _uuids = tizen1_utils.copyString(uuids),
+        bluetoothDevice;
+
+    bluetoothDevice = {
+        connectToServiceByUUID : function (uuid, successCallback, errorCallback) {
+            if (!_security.all && !_security.connectToServiceByUUID)
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+
+            if (typeof uuid !== "string")
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+            _validateCallbackType(successCallback, errorCallback);
+
+            if (uuids.join(",").indexOf(uuid) === -1) {
+                if (errorCallback) {
+                    errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+                }
+                return;
+            }
+
+            socketInfo = {
+                uuid : uuid,
+                protocol : "RFCOMM",
+                state : "OPEN",
+                peer : _data.bondDevice
+            };
+            bluetoothSocket = new BluetoothSocket(socketInfo.uuid, socketInfo.protocol, socketInfo.state, socketInfo.peer);
+            successCallback(bluetoothSocket);
+        }
+    };
+
+    bluetoothDevice.__defineGetter__("name", function () {
+        return _name;
+    });
+    bluetoothDevice.__defineGetter__("address", function () {
+        return _address;
+    });
+    bluetoothDevice.__defineGetter__("deviceClass", function () {
+        return _deviceClass;
+    });
+    bluetoothDevice.__defineGetter__("isBonded", function () {
+        return _isBonded;
+    });
+    bluetoothDevice.__defineGetter__("isTrusted", function () {
+        return _isTrusted;
+    });
+    bluetoothDevice.__defineGetter__("isConnected", function () {
+        return _isConnected;
+    });
+    bluetoothDevice.__defineGetter__("uuids", function () {
+        return _uuids;
+    });
+
+    return bluetoothDevice;
+};
+
+// The BluetoothSocket object
+BluetoothSocket = function (uuid, protocol, state, peer) {
+    var bluetoothSocket, msg, readData,
+        _uuid = tizen1_utils.copyString(uuid),
+        _protocol = tizen1_utils.copyString(protocol),
+        _state = tizen1_utils.copyString(state),
+        _peer = tizen1_utils.copy(peer);
+
+    bluetoothSocket = {
+        onmessage : null,
+        onclose : null,
+        onerror : null,
+        writeData : function (data) {
+            if (!_security.all && !_security.writeData)
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+
+            if (_state === "CLOSED")
+                return;
+
+            if (tizen1_utils.isValidArray(data))
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+            if (_data.remote.bondStatus === "bonding") {
+                event.trigger("dataArrived", [data]);
+            }
+            return data.length;
+        },
+        readData : function () {
+            if (!_security.all && !_security.readData)
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+
+            if (_state === "CLOSED")
+                return;
+
+            if (_data.remote.sentData && (_data.remote.bondStatus === "bonding")) {
+                readData = _stringToBytes(_data.remote.sentData);
+            } else {
+                readData = "";
+            }
+            return readData;
+        },
+        close : function () {
+            if (!_security.all && !_security.close)
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+
+            _state = "CLOSED";
+        }
+    };
+    bluetoothSocket.__defineGetter__("uuid", function () {
+        return _uuid;
+    });
+    bluetoothSocket.__defineGetter__("protocol", function () {
+        return _protocol;
+    });
+    bluetoothSocket.__defineGetter__("state", function () {
+        return _state;
+    });
+    bluetoothSocket.__defineGetter__("peer", function () {
+        return _peer;
+    });
+    return bluetoothSocket;
+};
+
+// The BluetoothClass object
+BluetoothClass = function (major, minor, services) {
+    var bluetoothClass, isClassDeviceService,
+        _major = tizen1_utils.copyString(major),
+        _minor = tizen1_utils.copyString(minor),
+        _services = tizen1_utils.copy(services);
+
+    bluetoothClass = {
+        hasService : function (service) {
+            var serviceOn = false, index;
+
+            if (typeof service !== "string")
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+            if (services.join(",").indexOf(service) !== -1) {
+                serviceOn = true;
+            }
+            return serviceOn;
+        }
+    };
+    bluetoothClass.__defineGetter__("major", function () {
+        return _major;
+    });
+    bluetoothClass.__defineGetter__("minor", function () {
+        return _minor;
+    });
+    bluetoothClass.__defineGetter__("services", function () {
+        return _services;
+    });
+    return bluetoothClass;
+};
+
+// The BluetoothServiceHandler object
+BluetoothServiceHandler = function (uuid, name, isConnected) {
+    var _uuid = tizen1_utils.copyString(uuid),
+        _name = tizen1_utils.copyString(name),
+        _isConnected = isConnected,
+        bluetoothServiceHandler;
+
+    bluetoothServiceHandler = {
+        onconnect : null,
+        unregister : function (successCallback, errorCallback) {
+            if (!_security.all && !_security.unregister)
+                throw new WebAPIError(errorcode.SECURITY_ERR);
+
+            tizen1_utils.validateCallbackType(successCallback, errorCallback);
+
+            if (_data.locServices === undefined) {
+                if (errorCallback) {
+                    errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+                }
+                return;
+            }
+            for (var index in _data.locServices) {
+                if (_data.locServices[index].serviceInfo.name === _name) {
+                    delete _data.locServices[index];
+                }
+            }
+            db.saveObject(_data.DB_BLUETOOTH_LOC_SERVICES_KEY, _data.locServices);
+            _data.regCallback = null;
+            successCallback();
+        }
+    };
+    bluetoothServiceHandler.__defineGetter__("uuid", function () {
+        return _uuid;
+    });
+    bluetoothServiceHandler.__defineGetter__("name", function () {
+        return _name;
+    });
+    bluetoothServiceHandler.__defineGetter__("isConnected", function () {
+        return _isConnected;
+    });
+    return bluetoothServiceHandler;
+};
+
+// The BluetoothClassDeviceMajor object
+BluetoothClassDeviceMajor = function () {
+    this.__defineGetter__("MISC", function () {
+        return 0x00;
+    });
+    this.__defineGetter__("COMPUTER", function () {
+        return 0x01;
+    });
+    this.__defineGetter__("PHONE", function () {
+        return 0x02;
+    });
+    this.__defineGetter__("NETWORK", function () {
+        return 0x03;
+    });
+    this.__defineGetter__("AUDIO_VIDEO", function () {
+        return 0x04;
+    });
+    this.__defineGetter__("PERIPHERAL", function () {
+        return 0x05;
+    });
+    this.__defineGetter__("IMAGING", function () {
+        return 0x06;
+    });
+    this.__defineGetter__("WEARABLE", function () {
+        return 0x07;
+    });
+    this.__defineGetter__("TOY", function () {
+        return 0x08;
+    });
+    this.__defineGetter__("HEALTH", function () {
+        return 0x09;
+    });
+    this.__defineGetter__("UNCATEGORIZED", function () {
+        return 0x1F;
+    });
+};
+
+// The BluetoothClassDeviceMinor object
+BluetoothClassDeviceMinor = function () {
+    this.__defineGetter__("COMPUTER_UNCATEGORIZED", function () {
+        return 0x00;
+    });
+    this.__defineGetter__("COMPUTER_DESKTOP", function () {
+        return 0x01;
+    });
+    this.__defineGetter__("COMPUTER_SERVER", function () {
+        return 0x02;
+    });
+    this.__defineGetter__("COMPUTER_LAPTOP", function () {
+        return 0x03;
+    });
+    this.__defineGetter__("COMPUTER_HANDHELD_PC_OR_PDA", function () {
+        return 0x04;
+    });
+    this.__defineGetter__("COMPUTER_PALM_PC_OR_PDA", function () {
+        return 0x05;
+    });
+    this.__defineGetter__("COMPUTER_WEARABLE", function () {
+        return 0x06;
+    });
+
+    this.__defineGetter__("PHONE_UNCATEGORIZED", function () {
+        return 0x00;
+    });
+    this.__defineGetter__("PHONE_CELLULAR", function () {
+        return 0x01;
+    });
+    this.__defineGetter__("PHONE_CORDLESS", function () {
+        return 0x02;
+    });
+    this.__defineGetter__("PHONE_SMARTPHONE", function () {
+        return 0x03;
+    });
+    this.__defineGetter__("PHONE_MODEM_OR_GATEWAY", function () {
+        return 0x04;
+    });
+    this.__defineGetter__("PHONE_ISDN", function () {
+        return 0x05;
+    });
+
+    this.__defineGetter__("AV_UNRECOGNIZED", function () {
+        return 0x00;
+    });
+    this.__defineGetter__("AV_WEARABLE_HEADSET", function () {
+        return 0x01;
+    });
+    this.__defineGetter__("AV_HANDSFREE", function () {
+        return 0x02;
+    });
+    this.__defineGetter__("AV_MICROPHONE", function () {
+        return 0x04;
+    });
+    this.__defineGetter__("AV_LOUDSPEAKER", function () {
+        return 0x05;
+    });
+    this.__defineGetter__("AV_HEADPHONES", function () {
+        return 0x06;
+    });
+    this.__defineGetter__("AV_PORTABLE_AUDIO", function () {
+        return 0x07;
+    });
+    this.__defineGetter__("AV_CAR_AUDIO", function () {
+        return 0x08;
+    });
+    this.__defineGetter__("AV_SETTOP_BOX", function () {
+        return 0x09;
+    });
+    this.__defineGetter__("AV_HIFI", function () {
+        return 0x0a;
+    });
+    this.__defineGetter__("AV_VCR", function () {
+        return 0x0b;
+    });
+    this.__defineGetter__("AV_VIDEO_CAMERA", function () {
+        return 0x0c;
+    });
+    this.__defineGetter__("AV_CAMCORDER", function () {
+        return 0x0d;
+    });
+    this.__defineGetter__("AV_MONITOR", function () {
+        return 0x0e;
+    });
+    this.__defineGetter__("AV_DISPLAY_AND_LOUDSPEAKER", function () {
+        return 0x0f;
+    });
+    this.__defineGetter__("AV_VIDEO_CONFERENCING", function () {
+        return 0x10;
+    });
+    this.__defineGetter__("AV_GAMING_TOY", function () {
+        return 0x12;
+    });
+
+    this.__defineGetter__("PERIPHERAL_UNCATEGORIZED", function () {
+        return 0;
+    });
+    this.__defineGetter__("PERIPHERAL_KEYBOARD", function () {
+        return 0x10;
+    });
+    this.__defineGetter__("PERIPHERAL_POINTING_DEVICE", function () {
+        return 0x20;
+    });
+    this.__defineGetter__("PERIPHERAL_KEYBOARD_AND_POINTING_DEVICE", function () {
+        return 0x30;
+    });
+    this.__defineGetter__("PERIPHERAL_JOYSTICK", function () {
+        return 0x01;
+    });
+    this.__defineGetter__("PERIPHERAL_GAMEPAD", function () {
+        return 0x02;
+    });
+    this.__defineGetter__("PERIPHERAL_REMOTE_CONTROL", function () {
+        return 0x03;
+    });
+    this.__defineGetter__("PERIPHERAL_SENSING_DEVICE", function () {
+        return 0x04;
+    });
+    this.__defineGetter__("PERIPHERAL_DEGITIZER_TABLET", function () {
+        return 0x05;
+    });
+    this.__defineGetter__("PERIPHERAL_CARD_READER", function () {
+        return 0x06;
+    });
+    this.__defineGetter__("PERIPHERAL_DIGITAL_PEN", function () {
+        return 0x07;
+    });
+    this.__defineGetter__("PERIPHERAL_HANDHELD_SCANNER", function () {
+        return 0x08;
+    });
+    this.__defineGetter__("PERIPHERAL_HANDHELD_INPUT_DEVICE", function () {
+        return 0x09;
+    });
+
+    this.__defineGetter__("IMAGING_UNCATEGORIZED", function () {
+        return 0x00;
+    });
+    this.__defineGetter__("IMAGING_DISPLAY", function () {
+        return 0x04;
+    });
+    this.__defineGetter__("IMAGING_CAMERA", function () {
+        return 0x08;
+    });
+    this.__defineGetter__("IMAGING_SCANNER", function () {
+        return 0x10;
+    });
+    this.__defineGetter__("IMAGING_PRINTER", function () {
+        return 0x20;
+    });
+
+    this.__defineGetter__("WEARABLE_WRITST_WATCH", function () {
+        return 0x01;
+    });
+    this.__defineGetter__("WEARABLE_PAGER", function () {
+        return 0x02;
+    });
+    this.__defineGetter__("WEARABLE_JACKET", function () {
+        return 0x03;
+    });
+    this.__defineGetter__("WEARABLE_HELMET", function () {
+        return 0x04;
+    });
+    this.__defineGetter__("WEARABLE_GLASSES", function () {
+        return 0x05;
+    });
+
+    this.__defineGetter__("TOY_ROBOT", function () {
+        return 0x01;
+    });
+    this.__defineGetter__("TOY_VEHICLE", function () {
+        return 0x02;
+    });
+    this.__defineGetter__("TOY_DOLL", function () {
+        return 0x03;
+    });
+    this.__defineGetter__("TOY_CONTROLLER", function () {
+        return 0x04;
+    });
+    this.__defineGetter__("TOY_GAME", function () {
+        return 0x05;
+    });
+
+    this.__defineGetter__("HEALTH_UNDEFINED", function () {
+        return 0x00;
+    });
+    this.__defineGetter__("HEALTH_BLOOD_PRESSURE_MONITOR", function () {
+        return 0x01;
+    });
+    this.__defineGetter__("HEALTH_THERMOMETER", function () {
+        return 0x02;
+    });
+    this.__defineGetter__("HEALTH_WEIGHING_SCALE", function () {
+        return 0x03;
+    });
+    this.__defineGetter__("HEALTH_GLUCOSE_METER", function () {
+        return 0x04;
+    });
+    this.__defineGetter__("HEALTH_PULSE_OXIMETER", function () {
+        return 0x05;
+    });
+    this.__defineGetter__("HEALTH_PULSE_RATE_MONITOR", function () {
+        return 0x06;
+    });
+    this.__defineGetter__("HEALTH_DATA_DISPLAY", function () {
+        return 0x07;
+    });
+    this.__defineGetter__("HEALTH_STEP_COUNTER", function () {
+        return 0x08;
+    });
+    this.__defineGetter__("HEALTH_BODY_COMPOSITION_ANALYZER", function () {
+        return 0x09;
+    });
+    this.__defineGetter__("HEALTH_PEAK_FLOW_MONITOR", function () {
+        return 0x0a;
+    });
+    this.__defineGetter__("HEALTH_MEDICATION_MONITOR", function () {
+        return 0x0b;
+    });
+    this.__defineGetter__("HEALTH_KNEE_PROSTHESIS", function () {
+        return 0x0c;
+    });
+    this.__defineGetter__("HEALTH_ANKLE_PROSTHESIS", function () {
+        return 0x0d;
+    });
+};
+
+// The BluetoothClassDeviceService object
+BluetoothClassDeviceService = function () {
+    this.__defineGetter__("LIMITED_DISCOVERABILITY", function () {
+        return 0x0001;
+    });
+    this.__defineGetter__("POSITIONING", function () {
+        return 0x0008;
+    });
+    this.__defineGetter__("NETWORKING", function () {
+        return 0x0010;
+    });
+    this.__defineGetter__("RENDERING", function () {
+        return 0x0020;
+    });
+    this.__defineGetter__("CAPTURING", function () {
+        return 0x0040;
+    });
+    this.__defineGetter__("OBJECT_TRANSFER", function () {
+        return 0x0080;
+    });
+    this.__defineGetter__("AUDIO", function () {
+        return 0x0100;
+    });
+    this.__defineGetter__("TELEPHONY", function () {
+        return 0x0200;
+    });
+    this.__defineGetter__("INFORMATION", function () {
+        return 0x0400;
+    });
+};
+
+_initialize();
+
+_self = function () {
+    function getDefaultAdapter() {
+        if (arguments.length > 0)
+            throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
+
+        if (!_data.adapter)
+            throw new WebAPIError(errorcode.UNKNOWN_ERR);
+
+        return _data.adapter;
+    }
+
+    function handleSubFeatures(subFeatures) {
+        for (var subFeature in subFeatures) {
+            if (_security[subFeature].length === 0) {
+                _security.all = true;
+                return;
+            }
+            _security.all = false;
+            utils.forEach(_security[subFeature], function (method) {
+                _security[method] = true;
+            });
+        }
+    }
+
+    var bluetooth = {
+        getDefaultAdapter : getDefaultAdapter,
+        handleSubFeatures : handleSubFeatures
+    };
+
+    bluetooth.__defineGetter__("DeviceMajor", function () {
+        return _data.bluetoothClassDeviceMajor;
+    });
+    bluetooth.__defineGetter__("DeviceMinor", function () {
+        return _data.bluetoothClassDeviceMinor;
+    });
+    bluetooth.__defineGetter__("DeviceService", function () {
+        return _data.bluetoothClassDeviceService;
+    });
+
+    return bluetooth;
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/pendingObject', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (pendingObj) {
+    var cancelFlag = true;
+    this.setCancelFlag = function (flag) {
+        cancelFlag = flag;
+    };
+    this.getCancelFlag = function () {
+        return cancelFlag;
+    };
+    this.userCancel = null;
+    this.pendingID = null;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/time', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var TZDate = require('ripple/platform/tizen/1.0/TZDate'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    db = require('ripple/db'),
+    tz = require('ripple/platform/tizen/1.0/timezone_info'),
+    _timeFormat = "h:m:s ap", _shortDateFormat = "d/m/y",
+    _longDateFormat = "D, M d y", _self;
+
+_self = {
+    getCurrentDateTime: function () {
+        return new TZDate();
+    },
+    setCurrentDateTime: function (dt) {
+        throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
+    },
+    getLocalTimezone: function () {
+        var tz = db.retrieve("tizen-timezone") || "Coordinated Universal Time";
+        return tz;
+    },
+    getAvailableTimezones: function () {
+        var ret = tz.getAllTimezone();
+        return ret;
+    },
+    getDateFormat: function (shortformat) {
+        if (shortformat !== undefined && shortformat !== null &&
+            typeof shortformat !== 'boolean') {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+        if (shortformat) {
+            return _shortDateFormat;
+        } else {
+            return _longDateFormat;
+        }
+    },
+    getTimeFormat: function () {
+        return _timeFormat;
+    },
+    isLeapYear: function (year) {
+        if (typeof year !== 'number') {
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+        return ((year % 4 === 0) && (year % 100 !== 0 || year % 400 === 0));
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/messaging', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var _self, service, i,
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    MessagingService = require('ripple/platform/tizen/1.0/MessagingService'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    TIZEN_MESSAGING_SMS = "messaging.sms",
+    TIZEN_MESSAGING_MMS = "messaging.mms",
+    TIZEN_MESSAGING_EMAIL = "messaging.email",
+    _security_check = {send: false, read: false, write: false},
+    _sms_service = null,
+    _mms_service = null,
+    _email_service = null;
+
+_self = function () {
+    this.getMessageServices = function (messageServiceType, onSuccess, onError, serviceId) {
+        var _getMsgServices, ret = [];
+
+        if (serviceId !== null && serviceId !== undefined &&
+            typeof serviceId !== 'string') {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (typeof messageServiceType !== 'string') {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+
+        _getMsgServices = function () {
+            switch (messageServiceType) {
+            case "messaging.sms":
+                if (_sms_service === null) {
+                    _sms_service = [new MessagingService("Tizen SMS Service 1", "SMS Service Name 1", TIZEN_MESSAGING_SMS, _security_check), new MessagingService("Tizen SMS Service 2", "SMS Service Name 2", TIZEN_MESSAGING_SMS, _security_check)];
+                }
+                service = _sms_service;
+                break;
+            case "messaging.mms":
+                if (_mms_service === null) {
+                    _mms_service = [new MessagingService("Tizen MMS Service", "MMS Service Name", TIZEN_MESSAGING_MMS, _security_check)];
+                }
+                service = _mms_service;
+                break;
+            case "messaging.email":
+                if (_email_service === null) {
+                    _email_service = [new MessagingService("Tizen Email Service", "Email Service Name", TIZEN_MESSAGING_EMAIL, _security_check)];
+                }
+                service = _email_service;
+                break;
+            default:
+                throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
+            }
+            if ((serviceId !== null) && (serviceId !== undefined)) {
+                for (i = 0; i < service.length; i++) {
+                    if (service[i].id === serviceId) {
+                        ret.push(service[i]);
+                    }
+                }
+                if (ret.length === 0) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                } else {
+                    setTimeout(function () {
+                        onSuccess(ret);
+                    }, 1);
+                }
+            } else {
+                setTimeout(function () {
+                    onSuccess(service);
+                }, 1);
+            }
+        };
+        return tizen1_utils.validateTypeMismatch(onSuccess, onError,
+                   "messaging:getMessageServices", _getMsgServices);
+    };
+    this.handleSubFeatures = function (subFeatures) {
+        if (tizen1_utils.isEmptyObject(subFeatures) ||
+            subFeatures["http://tizen.org/api/messaging"]) {
+            // all ok
+            _security_check.send = true;
+            _security_check.read = true;
+            _security_check.write = true;
+            return;
+        }
+        if (subFeatures["http://tizen.org/api/messaging.send"]) {
+            _security_check.send = true;
+        }
+        if (subFeatures["http://tizen.org/api/messaging.read"]) {
+            _security_check.send = true;
+        }
+        if (subFeatures["http://tizen.org/api/messaging.write"]) {
+            _security_check.send = true;
+        }
+    };
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/calendar', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    TZDate = require('ripple/platform/tizen/1.0/TZDate'),
+    CalendarItem = require('ripple/platform/tizen/1.0/CalendarItem'),
+    CalendarEvent = require('ripple/platform/tizen/1.0/CalendarEvent'),
+    CalendarTask = require('ripple/platform/tizen/1.0/CalendarTask'),
+    CalendarRecurrenceRule = require('ripple/platform/tizen/1.0/CalendarRecurrenceRule'),
+    Calendar,
+    CalendarStorage,
+    CalendarItemsStorage,
+    _DB_CALENDARS_KEY = "tizen1-db-calendars",
+    _watchers = [],
+    _calendars = {
+        EVENT: {},
+        TASK: {}
+    },
+    _calendarsStorage,
+    _security = {
+        "http://tizen.org/api/calendar": [],
+        "http://tizen.org/api/calendar.read": ["find", "addChangeListener"],
+        "http://tizen.org/api/calendar.write": ["add", "addBatch", "update", "updateBatch", "remove", "removeBatch"],
+        all: true
+    },
+    _self;
+
+function _isValidId(id) {
+    return (/[a-z]|[A-Z]|[0-9]|[\-]/).test(id);
+}
+
+function retrieveCalendars() {
+    _calendarsStorage = db.retrieveObject(_DB_CALENDARS_KEY) || {EVENT: {}, TASK: {}};
+}
+
+function saveCalendars() {
+    db.saveObject(_DB_CALENDARS_KEY, _calendarsStorage);
+}
+
+_self = function () {
+    var calendarManager;
+
+    // private
+    function isValidType(type) {
+        for (var t in _calendars) {
+            if (type === t)
+                return true;
+        }
+        return false;
+    }
+
+    function loadCalendars(type) {
+        var calsStorage, defCalendar, id, i, item;
+
+        retrieveCalendars();
+        calsStorage = _calendarsStorage[type];
+
+        if (tizen1_utils.isEmptyObject(calsStorage)) {
+            defCalendar = new Calendar(type, "DEF_CAL_" + type);
+
+            _calendars[type][defCalendar.id] = defCalendar;
+            calsStorage[defCalendar.id] = new CalendarStorage(defCalendar);
+        } else {
+            for (id in calsStorage) {
+                for (i in calsStorage[id].items) {
+                    item = calsStorage[id].items[i];
+                }
+                _calendars[type][id] = new Calendar(type, calsStorage[id].name, calsStorage[id].items, id, 0);
+            }
+        }
+    }
+
+    // public
+    function getCalendar(type, id) {
+        var calendar;
+
+        if (!isValidType(type) || !_isValidId(id))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        loadCalendars(type);
+
+        calendar = _calendars[type][id];
+        if (calendar === undefined)
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        return calendar;
+    }
+
+    function getCalendars(type, successCallback, errorCallback) {
+        function _getCalendars() {
+            if (!isValidType(type))
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+            loadCalendars(type);
+
+            if (_calendars.length !== 0) {
+                successCallback(utils.copy(_calendars[type]));
+            } else if (errorCallback) {
+                errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
+            }
+        }
+
+        return tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "calendar:getCalendars", _getCalendars);
+    }
+
+    function getDefaultCalendar(type) {
+        var id, calendar;
+
+        if (!isValidType(type))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        loadCalendars(type);
+
+        for (id in _calendars[type]) {
+            calendar = _calendars[type][id];
+            break;
+        }
+
+        if (calendar === undefined)
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        return calendar;
+    }
+
+    function handleSubFeatures(subFeatures) {
+        for (var subFeature in subFeatures) {
+            if (_security[subFeature].length === 0) {
+                _security.all = true;
+                return;
+            }
+            _security.all = false;
+            utils.forEach(_security[subFeature], function (method) {
+                _security[method] = true;
+            });
+        }
+    }
+
+    calendarManager = {
+        getCalendar:        getCalendar,
+        getCalendars:       getCalendars,
+        getDefaultCalendar: getDefaultCalendar,
+        handleSubFeatures:  handleSubFeatures
+    };
+
+    return calendarManager;
+};
+
+Calendar = function (type, name, storageItems, id, accountServiceId) {
+    var privateItems = {};
+    id = id || Math.uuid(null, 16);
+    accountServiceId = accountServiceId || 0;
+
+    // private
+    function createCalendarItem() {
+        var calendarItem = null;
+
+        switch (type) {
+        case "EVENT":
+            calendarItem = new CalendarEvent();
+            break;
+
+        case "TASK":
+            calendarItem = new CalendarTask();
+            break;
+
+        default:
+            break;
+        }
+
+        return calendarItem;
+    }
+
+    function isValidCalendarItemId(itemId) {
+        var i;
+
+        if (!_isValidId(itemId))
+            return false;
+
+        for (i in privateItems) {
+            if (i === itemId)
+                return true;
+        }
+
+        return false;
+    }
+
+    function loadCalendarItemInit(calendarItem, storageItem) {
+        calendarItem.description    = utils.copy(storageItem.description);
+        calendarItem.summary        = utils.copy(storageItem.summary);
+        calendarItem.isAllDay       = utils.copy(storageItem.isAllDay);
+        calendarItem.startDate      = new TZDate(new Date(storageItem.startDate));
+        calendarItem.duration       = utils.copy(storageItem.duration);
+        calendarItem.location       = utils.copy(storageItem.location);
+        calendarItem.geolocation    = utils.copy(storageItem.geolocation);
+        calendarItem.organizer      = utils.copy(storageItem.organizer);
+        calendarItem.visibility     = utils.copy(storageItem.visibility);
+        calendarItem.status         = utils.copy(storageItem.status);
+        calendarItem.priority       = utils.copy(storageItem.priority);
+        calendarItem.alarms         = utils.copy(storageItem.alarms);
+        calendarItem.categories     = utils.copy(storageItem.categories);
+        calendarItem.attendees      = utils.copy(storageItem.attendees);
+    }
+
+    function loadCalendarEventInit(calendarItem, storageItem) {
+        loadCalendarItemInit(calendarItem, storageItem);
+
+        calendarItem.endDate = new TZDate(new Date(storageItem.endDate));
+        calendarItem.availability = utils.copy(storageItem.availability);
+        calendarItem.recurrenceRule = utils.copy(storageItem.recurrenceRule);
+        calendarItem.expandRecurrence = function (startDate, endDate, successCallback, errorCallback) {
+            calendarItem.startDate = startDate;
+            calendarItem.endDate   = endDate;
+        };
+        calendarItem.frequency       = utils.copy(storageItem.frequency);
+        calendarItem.interval        = utils.copy(storageItem.interval);
+        calendarItem.untilDate       = storageItem.untilDate?new TZDate(new Date(storageItem.untilDate)):storageItem.untilDate;
+        calendarItem.occurrenceCount = utils.copy(storageItem.occurrenceCount);
+        calendarItem.daysOfTheWeek   = utils.copy(storageItem.daysOfTheWeek);
+        calendarItem.setPositions    = utils.copy(storageItem.setPositions);
+        calendarItem.exceptions      = utils.copy(storageItem.exceptions);
+    }
+
+    function loadCalendarTaskInit(calendarItem, storageItem) {
+        loadCalendarItemInit(calendarItem, storageItem);
+
+        calendarItem.endDate       = new TZDate(new Date(storageItem.endDate));
+        calendarItem.completedDate = storageItem.completedDate?new TZDate(new Date(storageItem.completedDate)):storageItem.completedDate;
+        calendarItem.progress      = utils.copy(storageItem.progress);
+    }
+
+    function loadCalendarItems() {
+        var i, calendarItem;
+
+        if (storageItems === undefined)
+            return;
+
+        for (i in storageItems) {
+            calendarItem = new CalendarItem(type, i, new TZDate(new Date(storageItems[i].lastModificationDate)));
+
+            if (type === "EVENT") {
+                loadCalendarEventInit(calendarItem, storageItems[i]);
+            } else {
+                loadCalendarTaskInit(calendarItem, storageItems[i]);
+            }
+
+            privateItems[i] = calendarItem;
+        }
+    }
+
+    function saveCalendarItems() {
+        _calendarsStorage[type][id].items = new CalendarItemsStorage(privateItems);
+        saveCalendars();
+    }
+
+    // public
+    function get(id) {
+        if (!isValidCalendarItemId(id))
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        return privateItems[id];
+    }
+
+    function add(item) {
+        if (!_security.all && !_security.add)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        // typecoerce
+        privateItems[item.id] = utils.copy(item);
+
+        saveCalendarItems();
+
+        for (var i in _watchers) {
+            _watchers[i].onitemsadded([utils.copy(item)]);
+        }
+    }
+
+    function addBatch(items, successCallback, errorCallback) {
+        if (!_security.all && !_security.addBatch)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        function _addBatch() {
+            var i;
+
+            // typecoerce items
+
+            for (i in items) {
+                privateItems[items[i].id] = utils.copy(items[i]);
+            }
+
+            saveCalendarItems();
+
+            for (i in _watchers) {
+                _watchers[i].onitemsadded(utils.copy(items));
+            }
+
+            successCallback(utils.copy(items));
+        }
+
+        return tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "calendar:addBatch", _addBatch);
+    }
+
+    function update(item, updateAllInstances) {
+        var calendarItem, i, j, attr;
+
+        if (!_security.all && !_security.update)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        // typecoerce item, updateAllInstances
+
+        if (!isValidCalendarItemId(item.id))
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        if (updateAllInstances) {
+            for (attr in privateItems[item.id]) {
+                if ((attr !== "id") && (attr !== "lastModificationDate") && (item[attr] !== undefined))
+                    privateItems[item.id][attr] = utils.copy(item[attr]);
+            }
+            for (i in _watchers) {
+                _watchers[i].onitemsupdated([utils.copy(privateItems[item.id])]);
+            }
+        } else {
+            calendarItem = createCalendarItem();
+
+            for (attr in privateItems[item.id]) {
+                if (attr !== "id" && attr !== "lastModificationDate") {
+                    if (item[attr] !== undefined)
+                        calendarItem[attr] = utils.copy(item[attr]);
+                    else
+                        calendarItem[attr] = utils.copy(privateItems[item.id][attr]);
+                }
+            }
+            add(calendarItem);
+            for (j in _watchers) {
+                _watchers[j].onitemsupdated([utils.copy(calendarItem)]);
+            }
+        }
+        saveCalendarItems();
+    }
+
+    function updateBatch(items, successCallback, errorCallback, updateAllInstances) {
+        var calendarItems = [], updatedItems = [];
+
+        if (!_security.all && !_security.updateBatch)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        function _updateBatch() {
+            var i, j, attr, calendarItem;
+
+            // typecoerce items updateAllInstances
+
+            for (i in items) {
+                if (!isValidCalendarItemId(items[i].id))
+                    throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+            }
+
+            if (updateAllInstances) {
+                for (i in privateItems) {
+                    for (j in items) {
+                        if (i === items[j].id) {
+                            for (attr in privateItems[i]) {
+                                if (attr !== "id" && attr !== "lastModificationDate" && items[j][attr] !== undefined)
+                                    privateItems[i][attr] = utils.copy(items[j][attr]);
+                            }
+                            saveCalendarItems();
+                            updatedItems.push(utils.copy(privateItems[i]));
+                        }
+                    }
+                }
+            } else {
+                for (i in items) {
+                    calendarItem = createCalendarItem();
+
+                    for (attr in privateItems[items[i].id]) {
+                        if (attr !== "id" && attr !== "lastModificationDate") {
+                            if (items[i][attr] !== undefined)
+                                calendarItem[attr] = utils.copy(items[i][attr]);
+                            else
+                                calendarItem[attr] = utils.copy(privateItems[items[i].id][attr]);
+                        }
+                    }
+
+                    add(calendarItem);
+                    updatedItems.push(utils.copy(calendarItem));
+                }
+            }
+
+            saveCalendarItems();
+            for (i in _watchers) {
+                _watchers[i].onitemsupdated(updatedItems);
+            }
+            successCallback(updatedItems);
+        }
+
+        return tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "calendar:updateBatch", _updateBatch);
+    }
+
+    function remove(id) {
+        var isFound = false, i, removedItem;
+
+        if (!_security.all && !_security.remove)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        if (!_isValidId(id))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (!isValidCalendarItemId(id))
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        for (i in privateItems) {
+            if (i === id) {
+                removedItem = utils.copy(privateItems[i]);
+                delete privateItems[i];
+                isFound = true;
+                break;
+            }
+        }
+
+        if (!isFound)
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        saveCalendarItems();
+        for (i in _watchers) {
+            _watchers[i].onitemsremoved(removedItem);
+        }
+    }
+
+    function removeBatch(ids, successCallback, errorCallback) {
+        var i, j, isFound = false, removedItems = [];
+
+        if (!_security.all && !_security.removeBatch)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        function _removeBatch() {
+            var i, j;
+
+            for (i in ids) {
+                if (!_isValidId(ids[i]))
+                    throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+                if (!isValidCalendarItemId(id))
+                    throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+            }
+
+            for (i in ids) {
+                isFound = false;
+                for (j in privateItems) {
+                    if (j === ids[i])
+                        isFound = true;
+                }
+                if (!isFound)
+                    throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+            }
+
+            for (i in ids) {
+                for (j in privateItems) {
+                    if (j === ids[i]) {
+                        removedItems.push(utils.copy(privateItems[j]));
+                        delete privateItems[j];
+                    }
+                }
+            }
+
+            saveCalendarItems();
+            successCallback(removedItems);
+            for (i in _watchers) {
+                _watchers[i].onitemsremoved(utils.copy(removedItems));
+            }
+        }
+
+        return tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "calendar:removeBatch", _removeBatch);
+    }
+
+    function find(successCallback, errorCallback, filter, sortMode) {
+        if (!_security.all && !_security.find)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        function _find() {
+            var i, calendarItems = [], result = [];
+
+            for (i in privateItems) {
+                calendarItems.push(privateItems[i]);
+            }
+
+            result = tizen1_utils.query(calendarItems, filter, sortMode);
+            successCallback(result);
+        }
+        return tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "calendar:find", _find);
+    }
+
+    function addChangeListener(successCallback, errorCallback) {
+        var watchId;
+
+        if (!_security.all && !_security.addChangeListener)
+            throw new WebAPIError(errorcode.SECURITY_ERR);
+
+        if (//(typeof successCallback !== "function") ||
+            (typeof errorCallback !== "function"))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        watchId = Math.uuid(null, 16);
+        _watchers[watchId] = successCallback;
+
+        return watchId;
+    }
+
+    function removeChangeListener(watchId) {
+        if (!_isValidId(watchId))
+            throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+
+        if (!_watchers[watchId])
+            throw new WebAPIError(errorcode.NOT_FOUND_ERR);
+
+        delete _watchers[watchId];
+    }
+
+    loadCalendarItems(type, privateItems, storageItems);
+
+    this.__defineGetter__("id", function () {
+        return id;
+    });
+    this.__defineGetter__("accountServiceId", function () {
+        return accountServiceId;
+    });
+    this.__defineGetter__("name", function () {
+        return name;
+    });
+
+    this.get                  = get;
+    this.add                  = add;
+    this.addBatch             = addBatch;
+    this.update               = update;
+    this.updateBatch          = updateBatch;
+    this.remove               = remove;
+    this.removeBatch          = removeBatch;
+    this.find                 = find;
+    this.addChangeListener    = addChangeListener;
+    this.removeChangeListener = removeChangeListener;
+};
+
+CalendarStorage = function (calendar) {
+    this.id               = calendar.id;
+    this.accountServiceId = calendar.accountServiceId;
+    this.name             = calendar.name;
+
+};
+
+CalendarItemsStorage = function (privateItems) {
+    var itemsStorage = {}, i, attr;
+
+    for (i in privateItems) {
+        itemsStorage[i] = {};
+        for (attr in privateItems[i]) {
+            if ((attr === "startDate" || attr === "endDate" || attr === "untilDate" || attr === "completedDate" || attr === "lastModificationDate") &&
+                (privateItems[i][attr] !== undefined)) {
+                itemsStorage[i][attr] = privateItems[i][attr].toString();
+            } else if (typeof privateItems[i] !== "function") {
+                itemsStorage[i][attr] = privateItems[i][attr];
+            }
+        }
+    }
+
+    return itemsStorage;
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/AlarmBase', function (require, module, exports) {
+/*\r
+ *  Copyright 2012 Intel Corporation.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+module.exports = function (id) {\r
+    id = id || Math.uuid(null, 16);\r
+\r
+    this.__defineGetter__("id", function () {\r
+        return id;\r
+    });\r
+    this.__defineSetter__("id", function (_id) {\r
+        id = _id;\r
+    });\r
+};\r
+
+});
+require.define('ripple/platform/tizen/1.0/vibration', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    deviceSettings = require('ripple/deviceSettings'),
+    constants = require('ripple/constants'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    emulatorBridge = require('ripple/emulatorBridge'),
+    curPost,
+    _self;
+
+function isVibratorOn() {
+    return deviceSettings.retrieve("Config.vibratingMode");
+}
+
+var vibrator = (function () {
+    var vibratorPattern,
+        isVibrating = false,
+        runTime = 0,
+        vibrateTimeout = null,
+        MILLILSECONDS_OF_ONE_VIBRATION = 100,
+        node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
+        movementIndex = 0,
+        movement = [{ left: -10 }, { left: 0 }, { left: 10 }, { left: 0 },
+                    {top: -10 }, { top: 0 }, {top: 10 }, { top: 0 }];
+
+    function _clearTimeout() {
+        if (vibrateTimeout) {
+            clearInterval(vibrateTimeout);
+            vibrateTimeout = null;        
+        }
+    }
+
+    function stopVibrate() {
+        isVibrating = false;
+        _clearTimeout();
+        node.css({left: 0, top: 0}, MILLILSECONDS_OF_ONE_VIBRATION);
+    }
+    
+    function vibrate() {
+        node.css(movement[movementIndex]);
+        movementIndex = (movementIndex + 1) % 8;
+    }
+    
+    function changePulse() {
+        if (emulatorBridge.document().hidden) {
+            return;
+        }
+
+        //run time
+        runTime = runTime + MILLILSECONDS_OF_ONE_VIBRATION;
+        if (curPost >= vibratorPattern.length) {
+            setTimeout(stopVibrate, 1);
+        }       
+        if (runTime > vibratorPattern[curPost]) {
+            curPost = curPost + 1;
+            runTime = 0;
+        } else {
+            if ((curPost % 2) === 0) {
+                vibrate();
+            }
+        }
+    } 
+  
+    function startVibrate(_pattern) {
+        if (!isVibratorOn()) 
+            return;
+
+        vibratorPattern = _pattern; 
+        _clearTimeout();
+        movementIndex = 0;      
+        if (_pattern) {
+            runTime = 0;
+            vibrateTimeout = setInterval(changePulse, MILLILSECONDS_OF_ONE_VIBRATION);
+        }    
+        isVibrating = true;
+    }
+    
+    return {
+        isVibrating: isVibrating,
+        startVibrate: startVibrate,
+        stopVibrate: stopVibrate
+    };
+}());
+
+_self = {
+    vibrate: function () {
+        var pattern = arguments[0],
+            i; 
+
+        // If vibrator is off, stop the vibration
+        event.on("VibratingModeChanged", function (value) {
+            if (value === false) {
+                vibrator.stopVibrate();
+            }
+        });
+        
+        //1. If the hidden attribute [PAGE-VISIBILITY] is set to true, abort these steps.
+        if (emulatorBridge.document().hidden) {
+            return;
+        }
+
+        //2. Let pattern be the value of the first argument.                     
+        if (!tizen1_utils.isValidArray(pattern)) {
+            pattern |= 0;
+        } else {
+            for (i = 0; i < pattern.length; i++) {
+                pattern[i] |= 0;
+            }
+        }
+
+        //3. If pattern is 0, or an empty list, cancel the pre-existing instance of the processing vibration patterns algorithm, if any, and abort these steps.    
+        if (pattern === 0 || (tizen1_utils.isValidArray(pattern) && pattern.length === 0)) {
+            vibrator.stopVibrate();
+            return;
+        }
+        
+        //4. If pattern is a list, proceed to the next step. Otherwise run the following substeps:
+        //a. Let list be an initially empty list, and add pattern to list.
+        //b. Let pattern be list.       
+        if (!tizen1_utils.isValidArray(pattern)) {
+            pattern = [pattern];
+        }
+
+        //5. If any entry of pattern exceeds an implementation-dependent limit, then the user agent may throw a NotSupportedError exception and abort these steps.
+              
+        //6. If the length of pattern is even, then remove the last entry in pattern. 
+        if (pattern.length % 2 === 0) {
+            pattern.pop();
+        }
+        
+        //7. Cancel the pre-existing instance of the processing vibration patterns algorithm, if any. 
+        if (vibrator.isVibrating) {
+            vibrator.stopVibrate();
+        }
+
+        curPost = 0;
+        vibrator.startVibrate(pattern);
+    }
+}; 
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/MessageStorage', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    Message = require('ripple/platform/tizen/1.0/Message'),
+    MessageBody = require('ripple/platform/tizen/1.0/MessageBody'),
+    Conversation = require('ripple/platform/tizen/1.0/Conversation'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    PrivMessage = require('ripple/platform/tizen/1.0/PrivMessage'),
+    MessageFolder = require('ripple/platform/tizen/1.0/MessageFolder'),
+    msg_utils = require('ripple/platform/tizen/1.0/msg_utils'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    TIZEN_DEFAULT_MSG_FROM = {"messaging.sms": "13572468",
+                              "messaging.mms": "13572468",
+                              "messaging.email": "tizen.simulator@tizen.org"};
+
+_self = function (messages, security_check) {
+    var message_storage = {},
+        _findMessage, _findConversation,
+        _processMessageChange, _processConversationChange,
+        _folders = {}, folderOpt = {},
+        _msgListeners = {},
+        _convListeners = {},
+        _folderListeners = {},
+        _security_check = security_check,
+        _messages = messages;
+
+    // init folders
+    folderOpt = {id: "INBOX", serviceId: _messages.id, contentType: _messages.type,
+                 path: "inbox", type: "INBOX", synchronizable: true};
+    _folders.INBOX = new MessageFolder(folderOpt);
+    folderOpt = {id: "OUTBOX", serviceId: _messages.id, contentType: _messages.type,
+                 path: "outbox", type: "OUTBOX", synchronizable: false};
+    _folders.OUTBOX = new MessageFolder(folderOpt);
+    folderOpt = {id: "DRAFT", serviceId: _messages.id, contentType: _messages.type,
+                 path: "draft", type: "DRAFTS", synchronizable: false};
+    _folders.DRAFT = new MessageFolder(folderOpt);
+    folderOpt = {id: "SENTBOX", serviceId: _messages.id, contentType: _messages.type,
+                 path: "sentbox", type: "SENTBOX", synchronizable: false};
+    _folders.SENTBOX = new MessageFolder(folderOpt);
+
+    event.on("MsgRecv", function (msg) {
+        // msg sent from panel to module
+        if (msg.priv.type !== _messages.type ||
+            msg.priv.serviceId !== _messages.id) {
+            return;
+        }
+        // trigger Message add
+        _processMessageChange([msg], "add");
+        _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
+
+        if (_messages.conv[msg.priv.conversationId].messageCount === 1) {
+            _processConversationChange([_messages.conv[msg.priv.conversationId]], "add");
+        } else {
+            _processConversationChange([_messages.conv[msg.priv.conversationId]], "update");
+        }
+    });
+
+    event.on("OutsideMessageReceived", function (msg) {
+        // msg sent from module to panel
+        if (msg.msg.priv.type !== _messages.type ||
+            msg.msg.priv.serviceId !== _messages.id) {
+            return;
+        }
+        // trigger conversation/Message add
+        _processMessageChange([msg.msg], "add");
+        _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
+
+        if (_messages.conv[msg.msg.priv.conversationId].messageCount === 1) {
+            _processConversationChange([_messages.conv[msg.msg.priv.conversationId]], "add");
+        } else {
+            _processConversationChange([_messages.conv[msg.msg.priv.conversationId]], "update");
+        }
+    });
+
+    event.on("MsgSentRst", function (rst) {
+        // ACK from panel when module sent a msg to panel
+        if (rst.priv.type !== _messages.type ||
+            rst.priv.serviceId !== _messages.id) {
+            return;
+        }
+        // trigger conversation/Message Update
+        _processMessageChange([rst], "update");
+        _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
+        _processConversationChange([_messages.conv[rst.priv.conversationId]], "update");
+    });
+
+    _findMessage = function (src, filter) {
+        var ret, foo = {};
+        switch (filter.attributeName) {
+        case "serviceId":
+            foo[filter.attributeName] = _messages.id;
+            ret = tizen1_utils.matchAttributeFilter([foo],
+                      filter.attributeName, filter.matchFlag, filter.matchValue);
+            if (ret.length === 0) {
+                ret = [];
+            } else {
+                // make an array
+                ret = utils.filter(src, function () { return true; });
+            }
+            break;
+        case "type":
+            foo[filter.attributeName] = _messages.type;
+            ret = tizen1_utils.matchAttributeFilter([foo],
+                      filter.attributeName, filter.matchFlag, filter.matchValue);
+            if (ret.length === 0) {
+                ret = [];
+            } else {
+                // make an array
+                ret = utils.filter(src, function () { return true; });
+            }
+            break;
+        case "id":
+        case "conversationId":
+        case "folderId":
+        case "from":
+        case "messageStatus":
+            ret = tizen1_utils.matchAttributeFilter(src,
+                      "priv." + filter.attributeName,
+                      filter.matchFlag, filter.matchValue);
+            break;
+        case "hasAttachment":
+            if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
+                throw (new WebAPIError(errorcode.INVALID_VALUES_ERR,
+                              "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
+            }
+            ret = tizen1_utils.matchAttributeBooleanFilter(src,
+                      "priv." + filter.attributeName, filter.matchValue);
+            break;
+        case "to":
+        case "cc":
+        case "bcc":
+            ret = tizen1_utils.matchAttributeArrayFilter(src,
+                      filter.attributeName, filter.matchFlag, filter.matchValue);
+            break;
+        case "body":
+            ret = tizen1_utils.matchAttributeFilter(src,
+                      filter.attributeName + ".plainBody",
+                      filter.matchFlag, filter.matchValue);
+            break;
+        case "subject":
+        case "inResponseTo":
+            ret = tizen1_utils.matchAttributeFilter(src, filter.attributeName,
+                      filter.matchFlag, filter.matchValue);
+            break;
+        case "isRead":
+        case "isHighPriority":
+            if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
+                throw (new WebAPIError(errorcode.INVALID_VALUES_ERR,
+                              "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
+            }
+            ret = tizen1_utils.matchAttributeBooleanFilter(src,
+                      filter.attributeName, filter.matchValue);
+            break;
+        case "timestamp":
+            ret = tizen1_utils.matchAttributeRangeFilter(src,
+                      "priv." + filter.attributeName,
+                      filter.initialValue, filter.endValue);
+            break;
+
+        case "attachments":
+            throw (new WebAPIError(errorcode.NOT_SUPPORTED_ERR,
+                                  "not support find by " + filter.attributeName));
+        default:
+            throw (new WebAPIError(errorcode.INVALID_VALUES_ERR,
+                                   "invalid attributeName"));
+        }
+        return ret;
+    };
+
+    _processMessageChange = function (messages, type) {
+        var i, j, ret = [], tmp,
+            operation = {"add": "messagesadded",
+                         "remove": "messagesremoved",
+                         "update": "messagesupdated"};
+
+        for (i in _msgListeners) {
+            ret = [];
+            if (_msgListeners[i].filter !== null) {
+                tmp = _findMessage(messages, _msgListeners[i].filter);
+            } else {
+                tmp = messages;
+            }
+            if (tmp.length !== 0) {
+                for (j = 0; j < tmp.length; j++) {
+                    ret.push(new Message(tmp[j].priv.type, tmp[j]));
+                }
+                _msgListeners[i].callback[operation[type]](ret);
+            }
+        }
+    };
+
+    _findConversation = function (src, filter) {
+        var ret, foo = {};
+        switch (filter.attributeName) {
+        case "type":
+            foo[filter.attributeName] = _messages.type;
+            ret = tizen1_utils.matchAttributeFilter([foo], filter.attributeName, filter.matchFlag, filter.matchValue);
+            if (ret.length === 0) {
+                ret = [];
+            } else {
+                // make an array
+                ret = utils.filter(_messages.conv, function () { return true; });
+            }
+            break;
+        case "id":
+        case "preview":
+        case "subject":
+        case "from":
+        case "lastMessageId":
+            ret = tizen1_utils.matchAttributeFilter(src, filter.attributeName, filter.matchFlag, filter.matchValue);
+            break;
+        case "to":
+        case "cc":
+        case "bcc":
+            ret = tizen1_utils.matchAttributeArrayFilter(src,
+                      filter.attributeName, filter.matchFlag, filter.matchValue);
+            break;
+        case "isRead":
+            if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
+                throw (new WebAPIError(errorcode.INVALID_VALUES_ERR,
+                              "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
+            }
+            ret = tizen1_utils.matchAttributeBooleanFilter(src,
+                      filter.attributeName, filter.matchValue);
+            break;
+        case "timestamp":
+        case "messageCount":
+        case "unreadMessages":
+            ret = tizen1_utils.matchAttributeRangeFilter(src,
+                      filter.attributeName,
+                      filter.initialValue, filter.endValue);
+            break;
+        default:
+            throw (new WebAPIError(errorcode.INVALID_VALUES_ERR,
+                                   "invalid attributeName"));
+        }
+        return ret;
+    };
+
+    _processConversationChange = function (conversations, type) {
+        var i, j, ret = [], tmp,
+            operation = {"add": "conversationsadded",
+                         "remove": "conversationsremoved",
+                         "update": "conversationsupdated"};
+
+        for (i in _convListeners) {
+            ret = [];
+            if (_convListeners[i].filter !== null) {
+                tmp = _findConversation(conversations, _convListeners[i].filter);
+            } else {
+                tmp = conversations;
+            }
+            if (tmp.length !== 0) {
+                for (j = 0; j < tmp.length; j++) {
+                    ret.push(new Conversation(tmp[j]));
+                }
+                _convListeners[i].callback[operation[type]](ret);
+            }
+        }
+    };
+
+    message_storage = {
+        addDraftMessage: function (_msg, onSuccess, onError) {
+            var m, msg = {}, opt = {}, _addDraft;
+
+            if (_security_check.write === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            if (msg_utils.setMsg(_msg, msg) === false) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+            _addDraft = function () {
+                opt.id = Math.uuid(8, 16);
+                opt.serviceId = _messages.id;
+                if ((msg.inResponseTo !== null) &&
+                    (_messages.msg[msg.inResponseTo] !== undefined)) {
+                    opt.conversationId = _messages.msg[msg.inResponseTo].conversationId;
+                } else {
+                    opt.conversationId = opt.id;
+                }
+                opt.folderId = "DRAFTS";
+                opt.type = _messages.type;
+                opt.timestamp = new Date();
+                opt.from = TIZEN_DEFAULT_MSG_FROM[_messages.type];
+                if (msg.attachments.length === 0) {
+                    opt.hasAttachment = false;
+                } else {
+                    opt.hasAttachment = true;
+                }
+                opt.messageStatus = "DRAFT";
+
+                m = new PrivMessage(msg, opt);
+                _messages.msg[m.priv.id] = m;  // local
+                msg_utils.saveMsg(_messages.msg[m.priv.id]);  // remote
+                // trigger message add
+                _processMessageChange([m], "add");
+                setTimeout(function () {
+                    onSuccess(new Message(m.priv.type, m));
+                }, 1);
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "messageStorage:addDraftMessage", _addDraft);
+        },
+
+        removeMessages: function (messages, onSuccess, onError) {
+            var _removeMsg;
+
+            if (_security_check.write === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            if (tizen1_utils.isValidArray(messages) === false) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+            if (messages.length === 0) {
+                throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
+            }
+            _removeMsg = function () {
+                var i, c, na_msg = "", msgToDel = [], convToDel = {}, delConv = [], updateConv = [];
+                // update conversation.
+                _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
+                for (i = 0; i < messages.length; i++) {
+                    if (_messages.msg[messages[i].id] === undefined) {
+                        na_msg += messages[i].id + ", ";
+                    } else {
+                        msgToDel.push(utils.copy(_messages.msg[messages[i].id]));
+                    }
+                    if (_messages.conv[messages[i].conversationId] !== undefined) {
+                        convToDel[messages[i].conversationId] = _messages.conv[messages[i].conversationId];
+                    }
+                }
+                if (na_msg === "") {
+                    for (i = 0; i < messages.length; i++) {
+                        // conversation updated at remote when msg is deleted
+                        msg_utils.delMsg(_messages.msg[messages[i].id]); // remote
+                        delete _messages.msg[messages[i].id]; // local
+                    }
+                    // update conversation
+                    _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
+                    for (c in convToDel) {
+                        if (_messages.conv[c] === undefined) {
+                            delConv.push(convToDel[c]);
+                        } else {
+                            updateConv.push(convToDel[c]);
+                        }
+                    }
+                    setTimeout(function () {
+                        onSuccess();
+                    }, 1);
+                    // trigger messages remove
+                    _processMessageChange(msgToDel, "remove");
+                    if (delConv.length > 0) {
+                        _processConversationChange(delConv, "remove");
+                    }
+                    if (updateConv.length > 0) {
+                        _processConversationChange(updateConv, "update");
+                    }
+                } else {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.NOT_FOUND_ERR,
+                                    na_msg + "not found !!"));
+                        }, 1);
+                    }
+                }
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "messageStorage:removeMessage", _removeMsg);
+        },
+
+        updateMessages: function (messages, onSuccess, onError) {
+            var _updateMsg;
+
+            if (_security_check.write === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            if (tizen1_utils.isValidArray(messages) === false) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+            if (messages.length === 0) {
+                throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
+            }
+            _updateMsg = function () {
+                var i, m, updateConv = {}, updateMsg = [], tmp,
+                    na_msg = "", invalid_msg = "";
+
+                // update conversation
+                _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
+                for (i = 0; i < messages.length; i++) {
+                    m = _messages.msg[messages[i].id];
+                    if (m === undefined) {
+                        // msg not found
+                        na_msg += messages[i].id + ", ";
+                    } else {
+                        if (m.priv.messageStatus === "DRAFT") {
+                            tmp = {};
+                            // allow update all writeable attr in draft
+                            if (msg_utils.setMsg(messages[i], tmp) === false) {
+                                invalid_msg += messages[i].id + ", ";
+                            }
+                        }
+                    }
+                }
+                if (invalid_msg !== "") {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.INVALID_VALUES_ERR,
+                                    invalid_msg + "invalid values"));
+                        }, 1);
+                    }
+                    return;
+                }
+                if (na_msg !== "") {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.NOT_FOUND_ERR,
+                                    na_msg + "not found !!"));
+                        }, 1);
+                    }
+                    return;
+                }
+
+                for (i = 0; i < messages.length; i++) {
+                    m = _messages.msg[messages[i].id];
+                    if (m.priv.messageStatus === "DRAFT") {
+                        msg_utils.setMsg(messages[i], m);
+                    } else {
+                        // only allow update isRead in other folders
+                        if (typeof messages[i].isRead === 'boolean') {
+                            m.isRead = messages[i].isRead;
+                            updateMsg.push(m);
+                            updateConv[m.priv.conversationId] = _messages.conv[m.priv.conversationId];
+                        }
+                    }
+                    msg_utils.saveMsg(m);
+                }
+                setTimeout(function () {
+                    onSuccess();
+                }, 1);
+
+                // trigger Message update
+                _processMessageChange(updateMsg, "update");
+
+                _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
+                // trigger conversation update
+                _processConversationChange(updateConv, "update");
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "messageStorage:updateMessage", _updateMsg);
+        },
+
+        findMessages: function (filter, onSuccess, onError, sort, _limit, _offset) {
+            var i, _findMsg, tmp, offset, limit, ret = [];
+
+            if (_security_check.read === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+
+            _findMsg = function () {
+                tmp = _findMessage(_messages.msg, filter);
+                if (tmp.length === 0) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                        }, 1);
+                    }
+                }
+
+                if ((_offset !== null) && (_offset !== undefined)) {
+                    offset = _offset;
+                } else {
+                    offset = 0;
+                }
+                if ((_limit !== null) && (_limit !== undefined)) {
+                    limit = Math.min(_limit + offset, tmp.length);
+                } else {
+                    limit = tmp.length;
+                }
+                for (i = offset; i < limit; i++) {
+                    ret.push(new Message(tmp[i].priv.type, tmp[i]));
+                }
+                setTimeout(function () {
+                    onSuccess(ret);
+                }, 1);
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError,
+                       "messageStorage:findMessages", _findMsg);
+        },
+
+        findConversations: function (filter, onSuccess, onError, sort, _limit, _offset) {
+            var i, _findConv, tmp, offset, limit, ret = [];
+
+            if (_security_check.read === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            // download conversation
+            _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
+
+            _findConv = function () {
+                tmp = _findConversation(_messages.conv, filter);
+                if (tmp.length === 0) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                        }, 1);
+                    }
+                }
+
+                if ((_offset !== null) && (_offset !== undefined)) {
+                    offset = _offset;
+                } else {
+                    offset = 0;
+                }
+                if ((_limit !== null) && (_limit !== undefined)) {
+                    limit = Math.min(_limit + offset, tmp.length);
+                } else {
+                    limit = tmp.length;
+                }
+                for (i = offset; i < limit; i++) {
+                    ret.push(new Conversation(tmp[i]));
+                }
+                setTimeout(function () {
+                    onSuccess(ret);
+                }, 1);
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError,
+                       "messageStorage:findConversations", _findConv);
+        },
+
+        removeConversations: function (conversations, onSuccess, onError) {
+            var i, _removeConv, na_msg = "", retConv = [], removeMsg = [];
+
+            if (_security_check.write === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            // download conversation
+            _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
+
+            if (tizen1_utils.isValidArray(conversations) === false) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+            if (conversations.length === 0) {
+                throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
+            }
+            _removeConv = function () {
+                for (i = 0; i < conversations.length; i++) {
+                    if (_messages.conv[conversations[i].id] === undefined) {
+                        na_msg += conversations[i].id + ", ";
+                    } else {
+                        retConv.push(_messages.conv[conversations[i].id]);
+                        for (var m in _messages.msg) {
+                            if (_messages.msg[m].priv.conversationId === conversations[i].id) {
+                                removeMsg.push(_messages.msg[m]);
+                            }
+                        }
+                    }
+                }
+                if (na_msg === "") {
+                    for (i = 0; i < removeMsg.length; i++) {
+                        // conversation updated at remote
+                        msg_utils.delMsg(removeMsg[i]);  // remote
+                        delete _messages.msg[removeMsg[i].priv.id]; // local
+                    }
+                    // trigger msg(retMsg)/conv(retConv) delete update
+                    _processMessageChange(removeMsg, "remove");
+                    _processConversationChange(retConv, "remove");
+                    setTimeout(function () {
+                        onSuccess();
+                    }, 1);
+                } else {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.NOT_FOUND_ERR,
+                                    na_msg + "not found !!"));
+                        }, 1);
+                    }
+                }
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError, "messageStorage:removeConversations", _removeConv);
+        },
+
+        findFolders: function (filter, onSuccess, onError) {
+            var ret = [], tmp, i, _findFolders;
+
+            if (_security_check.read === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            _findFolders = function () {
+                switch (filter.attributeName) {
+                case "id":
+                case "serviceId":
+                case "contentType":
+                case "name":
+                case "path":
+                case "type":
+                    tmp = tizen1_utils.matchAttributeFilter(_folders,
+                              filter.attributeName, filter.matchFlag,
+                              filter.matchValue);
+                    break;
+                case "synchronizable":
+                    if (filter.matchFlag !== "EXACTLY" ||
+                        typeof filter.matchValue !== "boolean") {
+                        throw (new WebAPIError(errorcode.INVALID_VALUES_ERR,
+                                      "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
+                    }
+                    tmp = tizen1_utils.matchAttributeBooleanFilter(_folders,
+                              filter.attributeName, filter.matchValue);
+                    break;
+                case "parentId":
+                    if (filter.matchValue === null) {
+                        tmp = utils.filter(_folders, function (o) { return o.parentId === null; });
+                    } else {
+                        tmp = tizen1_utils.matchAttributeFilter(_folders,
+                                  filter.attributeName, filter.matchValue);
+                    }
+                    break;
+                default:
+                    throw (new WebAPIError(errorcode.INVALID_VALUES_ERR,
+                                           "invalid attributeName"));
+                }
+                if (tmp.length === 0) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
+                        }, 1);
+                    }
+                }
+                for (i = 0; i < tmp.length; i++) {
+                    ret.push(new MessageFolder(tmp[i]));
+                }
+                setTimeout(function () {
+                    onSuccess(ret);
+                }, 1);
+            };
+            return tizen1_utils.validateTypeMismatch(onSuccess, onError,
+                       "messageStorage:findFolders", _findFolders);
+        },
+
+        addMessagesChangeListener: function (msgCallback, filter) {
+            var watchId, msgListener = {};
+
+            if (_security_check.read === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            if (msgCallback === undefined || msgCallback === null ||
+                ((msgCallback !== undefined && msgCallback !== null) && (
+                typeof msgCallback.messagesadded !== 'function' ||
+                typeof msgCallback.messagesupdated !== 'function' ||
+                typeof msgCallback.messagesremoved !== 'function'))) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+
+            watchId = Number(Math.uuid(8, 10));
+            msgListener.callback = msgCallback;
+            msgListener.filter = filter || null;
+            _msgListeners[watchId] = msgListener;
+            return watchId;
+        },
+
+        addConversationsChangeListener: function (convCallback, filter) {
+            var watchId, convListener = {};
+
+            if (_security_check.read === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            if (convCallback === undefined || convCallback === null ||
+                ((convCallback !== undefined && convCallback !== null) && (
+                typeof convCallback.conversationsadded !== 'function' ||
+                typeof convCallback.conversationsupdated !== 'function' ||
+                typeof convCallback.conversationsremoved !== 'function'))) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+
+            watchId = Number(Math.uuid(8, 10));
+            convListener.callback = convCallback;
+            convListener.filter = filter || null;
+            _convListeners[watchId] = convListener;
+            return watchId;
+        },
+
+        addfoldersChangeListener: function (callback, filter) {
+            var watchId, folderListener = {};
+
+            if (_security_check.read === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            if (callback === undefined || callback === null ||
+                ((callback !== undefined && callback !== null) && (
+                typeof callback.foldersadded !== 'function' ||
+                typeof callback.foldersupdated !== 'function' ||
+                typeof callback.foldersremoved !== 'function'))) {
+                throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+            }
+
+            watchId = Number(Math.uuid(8, 10));
+            folderListener.callback = callback;
+            folderListener.filter = filter || null;
+            _folderListeners[watchId] = folderListener;
+            return watchId;
+        },
+
+        removeChangeListener: function (watchid) {
+            if (_security_check.read === false) {
+                throw (new WebAPIError(errorcode.SECURITY_ERR));
+            }
+            if (_msgListeners[watchid] !== undefined) {
+                delete _msgListeners[watchid];
+                return;
+            }
+            if (_convListeners[watchid] !== undefined) {
+                delete _convListeners[watchid];
+                return;
+            }
+            if (_folderListeners[watchid] !== undefined) {
+                delete _folderListeners[watchid];
+                return;
+            }
+            throw (new WebAPIError(errorcode.NOT_FOUND_ERR));
+        }
+
+    };
+    return message_storage;
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/tizen/1.0/routeBackend_navigation', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    lbs_utils = require('ripple/platform/tizen/1.0/lbs_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    SimpleCoordinates = require('ripple/platform/tizen/1.0/SimpleCoordinates'),
+    RouteWaypoint,
+    RouteDistance,
+    RouteDuration,
+    RouteStep,
+    RouteSegment,
+    RouteRequestOptions,
+    RouteResultSummary,
+    RouteResult,
+    LocationServiceProvider = {},
+    _data = {
+        positionDistance: {},
+        positionDuration: {},
+        routeProvider: {},
+        routes: [],
+        RouteDistanceUnit: ["M", "KM", "MI", "FT"],
+        providers: [],
+        path: []
+    }, 
+    _self;
+
+// The RouteWaypoint object
+RouteWaypoint = function () {
+    return {
+        position: {
+            latitude: 0,
+            longitude: 0
+        },
+        isStopover: true
+    };
+};
+
+// The RouteDistance object
+RouteDistance = function () {
+    return {
+        text : "Distance",
+        value : "0",
+        unit : "KM "
+    };
+};
+
+// The RouteDuration object
+RouteDuration = function () {
+    return {
+        text : "Duration",
+        value : "0" // The duration in a seconds
+    };
+};
+
+// The RouteStep object
+RouteStep = function () {
+    var _self = {
+        mode: "",        // The way of the travel, for example: car, bike, foot
+        instruction: "", // The instruction of this step
+        points: []       // The points of this step
+    };
+
+    _self.origin      = new SimpleCoordinates(0, 0);
+    _self.destination = new SimpleCoordinates(0, 0);
+    _self.distance    = new RouteDistance();
+    _self.duration    = new RouteDuration();
+
+    return _self;
+};
+// The RouteSegment object
+RouteSegment = function () {
+    var _self = {
+        steps: []
+    };
+
+    _self.origin      = new SimpleCoordinates(0, 0);
+    _self.destination = new SimpleCoordinates(0, 0);
+    _self.distance    = new RouteDistance();
+    _self.duration    = new RouteDuration();
+
+    return _self;
+};
+
+// The RouteRequestOptions object
+RouteRequestOptions = function () {
+    return {
+        mode: "", // CAR, BIKE
+        unit: "KM",
+        routeGoal: "SHORTEST",
+        constraints: ["HIGHWAY", "TOLL", "UNPAVED"],
+        wayPoints: [],
+        maxResults: 1
+    };
+};
+
+// The RouteResultSummary object
+RouteResultSummary = function () {
+    var _self = {};
+
+    _self.origin        = new SimpleCoordinates(0, 0);
+    _self.destination   = new SimpleCoordinates(0, 0);
+    _self.totalDistance = new RouteDistance();
+    _self.totalDuration = new RouteDuration();
+
+    return _self;
+};
+
+// The RouteResult object
+RouteResult = function () {
+    var _self, jsonStr, jsonObj;
+    jsonObj = { 
+            "type" : "Point",
+            "coordinates" : []
+        };
+    jsonStr = JSON.stringify(jsonObj);
+    _self = {
+        segments : [],
+        toGeoJSON : function () {
+                return jsonStr;
+            }
+    };
+    _self.summary = new RouteResultSummary();
+    return _self;
+};
+
+function calcDegree(distance) { 
+    return distance * Math.PI / 180.0;
+} 
+
+//calcute the distance
+function  calculateDistance(lat1, lat2, lon1, lon2) {
+    var R = 6371, dLat, dLon, a, c, distance; // km
+    dLat = calcDegree(parseFloat(lat2) - parseFloat(lat1));
+    dLon = calcDegree(parseFloat(lon2) - parseFloat(lon1));
+    
+    lat1 = calcDegree(lat1);
+    lat2 = calcDegree(lat2);
+
+    a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
+             Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2); 
+    c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 
+    distance = R * c;
+    return distance;
+}
+
+function calculateDuration(mode, distance) {
+    var duration, v;
+    switch (mode) {
+    case "motorcar" :
+        v = 50;
+        duration = distance / v;
+        break;
+    case "bicycle" :
+        v = 20;
+        duration = distance / v;
+        break;
+    case "foot" :
+        v = 5;
+        duration = distance / v;
+        break;
+    default:
+        duration = 0;
+    }
+    return duration;
+}
+
+function optimalWay(points, mode) {
+    var steps = [], startLatitude, startLongitude, originLocation, endLatitude, endLongitude,
+    destinationLocation, step, distance, segment, result, i, routeDistance, routeDuration;
+    for (i = 0;i < points.length - 1;i++) {
+        startLatitude       = points[i].lat;
+        startLongitude      = points[i].lon;
+        originLocation      = new SimpleCoordinates(startLatitude, startLongitude);
+        endLatitude         = points[i + 1].lat;
+        endLongitude        = points[i + 1].lon;
+        destinationLocation = new SimpleCoordinates(endLatitude, endLongitude);
+        step                = new RouteStep();
+        step.origin         = originLocation;
+        step.destination    = destinationLocation;
+        distance            = calculateDistance(startLatitude, endLatitude, startLongitude, endLongitude);
+        routeDistance       = new RouteDistance();
+        routeDistance.value = distance;
+        routeDistance.unit  = "km";
+        step.distance       = routeDistance;
+        routeDuration       = new RouteDuration();
+        routeDuration.value = calculateDuration(mode, distance);
+        step.duration       = routeDuration;
+        steps.push(step);
+    }
+    return steps;
+}
+
+function existInSupports(str, array) {
+    for (var i in array) {
+        if (str === array[i]) {
+            return true;
+        }
+    }
+    return false;
+}
+
+function navigation(searchStr, flat, flon, tlat, tlon, v, fast) {
+    var positions = [];
+
+    _data.positionDistance = {};
+    _data.positionDuration = {};
+    jQuery.ajax({
+        type : "get",
+        async : false,
+        url : searchStr,
+        data : {
+            flat : flat,
+            flon : flon,
+            tlat : tlat,
+            tlon : tlon,
+            v : v,
+            fast : fast,
+            layer : 'mapnik',
+            format : "geojson"
+        },
+        contentType : "application/json; charset=utf-8",
+        dataType : "json",
+        cache : false,
+        success : function (data) {
+            $.each(data.coordinates, function (i, item) {
+                var point = {};
+                point.lon = item[0];
+                point.lat = item[1];
+                positions.push(point);
+            });
+            $.each(data.properties, function (i, item) {
+                if (typeof item === "number") {
+                    _data.positionDistance = new RouteDistance();
+                    _data.positionDistance.value = item;
+                    _data.positionDistance.unit = "km";
+                    _data.positionDuration = new RouteDuration();
+                    _data.positionDuration.value = calculateDuration(v, item);
+                }
+            });
+        },
+        error : function (errorCB) {
+            if (errorCB) {
+                setTimeout(function () {
+                    errorCB(new WebAPIError(errorcode.NETWORK_ERR));
+                }, 1);
+            }
+        }
+    });
+    return positions;
+}
+
+
+function filterWaypoints(routeWaypoints) {
+    var mathWaypoints = [], i;
+    for (i in routeWaypoints) {
+        if (routeWaypoints[i].position.latitude !== "" &&
+            routeWaypoints[i].position.latitude !== undefined &&
+            routeWaypoints[i].position.latitude !== null &&
+            routeWaypoints[i].position.longitude !== null &&
+            routeWaypoints[i].position.longitude !== "" &&
+            routeWaypoints[i].position.longitude !== undefined) {
+            mathWaypoints.push(routeWaypoints[i]);
+        }
+    }
+    return mathWaypoints;
+}
+
+module.exports = function (prop) {
+    var _self = new lbs_utils.LocationServiceProvider(prop);
+
+    _self.supportedGoals       = ["SHORTEST", "FASTEST", "MOST_SCENIC", "SIMPLEST", "CHEAPEST", "SAFEST" ];
+    _self.supportedModes       = ["motorcar", "bicycle", "foot"];
+    _self.supportedConstraints = ["HIGHWAY", "TOLL", "UNPAVED", "BORDER", "GRAVEL_PAVING", "TUNNEL", "BRIDGE", "LEFT_TURN", "CARPOOL", "HAZARDOUS_CARGO" ];
+    _self.supportsWayPoints    = true;
+    _self.find = function (origin, destination, successCallback, errorCallback, options) {
+        function _find() {
+            var flat, flon, tlat, tlon, v, fast, layer, mapnik, format, searchStr, mode, result,
+                points = [],
+                routeWaypoints = [],
+                segmentPositions = [],
+                positions = [],
+                segments = [],
+                totalDistances = 0, totalDurations = 0,
+                k, key, segment, startPosition, endPosition,
+                summary, distance, duration;
+
+            v = options.mode;
+            //init
+            if (!existInSupports(v, _self.supportedModes)) {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            if (!existInSupports(options.routeGoal, _self.supportedGoals)) {
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+            }
+            switch (options.routeGoal) {
+            case "SHORTEST":
+                fast = 0;
+                break;
+
+            case "FASTEST":
+                fast = 1;
+                break;
+
+            case "SIMPLEST":
+                break;
+
+            case "MOST_SCENIC":
+                break;
+
+            case "CHEAPEST":
+                break;
+
+            case "SAFEST":
+                break;
+
+            default:
+                fast = 0;
+            }
+            searchStr      = "http://www.yournavigation.org/api/dev/gosmore.php";
+            routeWaypoints = options.wayPoints;
+            routeWaypoints = filterWaypoints(routeWaypoints);
+            segmentPositions.push(origin);
+
+            if (routeWaypoints.length > 0) {
+                for (k in routeWaypoints) {
+                    segmentPositions.push(routeWaypoints[k].position);
+                }
+            }
+            segmentPositions.push(destination);
+
+            for (key = 0; key < segmentPositions.length - 1; key++) {
+                segment             = new RouteSegment();
+                startPosition       = segmentPositions[key];
+                endPosition         = segmentPositions[key + 1];
+                segment.origin      = startPosition;
+                segment.destination = endPosition;
+                flat                = startPosition.latitude;
+                flon                = startPosition.longitude;
+                tlat                = endPosition.latitude;
+                tlon                = endPosition.longitude;
+                positions           = navigation(searchStr, flat, flon, tlat, tlon, v, fast);
+                segment.steps       = optimalWay(positions, v);
+                segment.distance    = _data.positionDistance;
+                totalDistances     += _data.positionDistance.value;
+                segment.duration    = _data.positionDuration;
+                totalDurations     += _data.positionDuration.value;
+                segments.push(segment);
+            }
+            result                = new RouteResult();
+            summary               = new RouteResultSummary();
+            summary.origin        = segmentPositions[0];
+            summary.destination   = segmentPositions[segmentPositions.length - 1];
+            distance              = new RouteDistance();
+            distance.value        = totalDistances;
+            distance.unit         = "km";
+            summary.totalDistance = distance;
+            duration              = new RouteDuration();
+            duration.value        = totalDurations;
+            summary.totalDuration = duration;
+            result.segments       = segments;
+            result.summary        = summary;
+            successCallback(result);
+        }
+
+        tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find);
+    };
+
+    return _self;
+};
+});
+require.define('ripple/platform/tizen/1.0/geoBackend_local', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('ripple/db'), 
+    utils = require('ripple/utils'),
+    lbs = require('ripple/platform/tizen/1.0/lbs_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    PendingObject = require('ripple/platform/tizen/1.0/pendingObject'),
+    PendingOperation = require('ripple/platform/tizen/1.0/pendingoperation'),
+    SimpleCoordinates = require('ripple/platform/tizen/1.0/SimpleCoordinates'),
+    GeocodeResult = require('ripple/platform/tizen/1.0/GeocodeResult'),
+    _GEO_OBJECTS = "tizen1.0-geocode-objects",
+    _get, _save, _geoList_init, GeoEntry,
+    _checkAddressType, _transAddressStr,
+    _geocodeByString, _findCoordsByString, _geocodeByAddress,
+    _reverseGeocodeBySimple, _reverseGeocodeByGeo, _checkCoordsType,
+    _self, _geoList = [],
+    _PENDING_TIME = 10;
+
+function _get() {
+    var geoList = [],
+        data = db.retrieveObject(_GEO_OBJECTS);
+    
+    utils.forEach(data, function (geo) {
+        geoList.push(geo);
+    });
+    return geoList;
+}
+
+function _save() {
+    db.saveObject(_GEO_OBJECTS, _geoList);
+}
+
+function _geoList_init() {
+    var entry;
+    _geoList = _get();
+
+    /* Put some default data if database is empty */
+    if (_geoList.length === 0) {
+        entry = new GeoEntry(new lbs.StructuredAddress({
+            country : "UK",
+            region : "London",
+            county : "Lambeth",
+            city : "London",
+            street : "Westminster Bridge Road",
+            streetNumber : "1",
+            premises : "Riverside Building",
+            additionalInformation : "London Eye",
+            postalCode : "SE1 7PB"
+        }),
+            new lbs.GeoCoordinates({
+            latitude : 51.510452,
+            longitude : -0.119820,
+            altitude : 0,
+            accuracy : 0,
+            altitudeAccuracy : 0,
+            heading : 0,
+            speed : 0
+        }));
+        _geoList.push(entry);
+        entry = new GeoEntry(new lbs.StructuredAddress({
+            country : "UK",
+            city : "London",
+            street : "Baker Street",
+            streetNumber : "221B",
+            postalCode : "NW1 6XE"
+        }),
+            new lbs.GeoCoordinates({
+            latitude : 51.524552,
+            longitude : -0.158615,
+            altitude : 0,
+            accuracy : 0,
+            altitudeAccuracy : 0,
+            heading : 0,
+            speed : 0
+        }));
+        _geoList.push(entry);
+        entry = new GeoEntry(new lbs.StructuredAddress({
+            country : "US",
+            region : "OR",
+            city : "Portland",
+            street : "SE Water Ave",
+            streetNumber : "1945",
+            additionalInformation : "OMSI",
+        }),
+            new lbs.GeoCoordinates({
+            latitude : 45.508490,
+            longitude : -122.665953,
+            altitude : 0,
+            accuracy : 0,
+            altitudeAccuracy : 0,
+            heading : 0,
+            speed : 0
+        }));
+        _geoList.push(entry);
+        entry = new GeoEntry(new lbs.StructuredAddress({
+            country : "US",
+            region : "OR",
+            city : "Portland",
+            street : "NW Pittock Drive",
+            streetNumber : "3229",
+            additionalInformation : "Pittock Mansion",
+        }),
+            new lbs.GeoCoordinates({
+            latitude : 45.531365,
+            longitude : -122.716255,
+            altitude : 0,
+            accuracy : 0,
+            altitudeAccuracy : 0,
+            heading : 0,
+            speed : 0
+        }));
+        _geoList.push(entry);
+        entry = new GeoEntry(new lbs.StructuredAddress({
+            region : "OR",
+            city : "Hillsboro",
+            street : "NE 25th St",
+            streetNumber : "2111",
+            postalCode : "97124"
+        }),
+            new lbs.GeoCoordinates({
+            latitude : 45.543479,
+            longitude : -122.9621601,
+            altitude : 0,
+            accuracy : 0,
+            altitudeAccuracy : 0,
+            heading : 0,
+            speed : 0
+        }));
+        _geoList.push(entry);
+        _save();
+    }
+}
+
+function _pendingOperate(operate) {
+    var pendingObj, pendingOperation, i, argumentVector = [];
+
+    for (i = 0; i < arguments.length - 1; i++)
+        argumentVector[i] = arguments[i + 1];
+
+    pendingObj = new PendingObject();
+
+    pendingObj.pendingID = window.setTimeout(function () {
+        pendingObj.setCancelFlag(false);
+        operate.apply(this, argumentVector);
+    }, _PENDING_TIME);
+
+    pendingOperation = new PendingOperation(pendingObj);
+
+    return pendingOperation;
+}
+
+function GeoEntry(addr, coord) {
+    var _self;
+    _self = {
+        address : addr || null,
+        coordinate : coord || null
+    };
+    return _self;
+}
+
+function SortMode() {
+    var _self;
+    _self = {
+        attributeName : "",
+        order : "ASC"
+    };
+    return _self;
+}
+
+function _transAddressStr(addr) {
+    var str = "";
+    if (addr.additionalInformation !== null && addr.additionalInformation !== undefined)
+        str = str + addr.additionalInformation + ", ";
+    if (addr.premises !== null && addr.premises !== undefined)
+        str = str + addr.premises + ", ";
+    if (addr.streetNumber !== null && addr.streetNumber !== undefined)
+        str = str + addr.streetNumber + " ";
+    if (addr.street !== null && addr.street !== undefined)
+        str = str + addr.street + ", ";
+    if (addr.city !== null && addr.city !== undefined)
+        str = str + addr.city + ", ";
+    if (addr.county !== null && addr.county !== undefined)
+        str = str + addr.county + ", ";
+    if (addr.region !== null && addr.region !== undefined)
+        str = str + addr.region + ", ";
+    if (addr.country !== null && addr.country !== undefined)
+        str = str + addr.country + ", ";
+    if (addr.postalCode !== null && addr.postalCode !== undefined)
+        str = str + addr.postalCode;
+
+    if (str.lastIndexOf(", ") === str.length - 2)
+        str = str.slice(0, -2);
+    return str;
+}
+
+function _concatAddress(addr) {
+    var str = "";
+    if (addr.additionalInformation !== null && addr.additionalInformation !== undefined)
+        str = str + addr.additionalInformation + " ";
+    if (addr.premises !== null && addr.premises !== undefined)
+        str = str + addr.premises + " ";
+    if (addr.streetNumber !== null && addr.streetNumber !== undefined)
+        str = str + addr.streetNumber + " ";
+    if (addr.street !== null && addr.street !== undefined)
+        str = str + addr.street + " ";
+    if (addr.city !== null && addr.city !== undefined)
+        str = str + addr.city + " ";
+    if (addr.county !== null && addr.county !== undefined)
+        str = str + addr.county + " ";
+    if (addr.region !== null && addr.region !== undefined)
+        str = str + addr.region + " ";
+    if (addr.country !== null && addr.country !== undefined)
+        str = str + addr.country + " ";
+    if (addr.postalCode !== null && addr.postalCode !== undefined)
+        str = str + addr.postalCode;
+
+    return str;
+}
+
+function _findCoordsByString(address) {
+    var array = [], reg, str, searchAddr, pieces, i;
+    if (address.length === 0)
+        return array;
+
+    pieces = address.split(",");
+    searchAddr = "";
+    for (i = 0; i < pieces.length; i++) {
+        searchAddr = searchAddr + pieces[i];
+    }
+    reg = new RegExp(searchAddr, "i");
+    
+    utils.forEach(_geoList, function (item) {
+        str = _concatAddress(item.address);
+        if (str.search(reg) !== -1)
+            array.push(new GeocodeResult(item.coordinate.latitude, item.coordinate.longitude));
+    });
+
+    return array;
+}
+
+function _geocodeByString(address, successCB, errorCB, options) {
+    var array;
+    array = _findCoordsByString(address);
+    successCB(array);
+}
+
+function _findCoordsByAddress(addr) {
+    var array = [], select = false, i;
+    for (i = 0; i < _geoList.length; i++) {
+        select = false;
+        if (addr.country !== null && addr.country !== undefined) {
+            if (addr.country === _geoList[i].address.country)
+                select = true;
+            else
+                continue;
+        }
+        
+        if (addr.region !== null && addr.region !== undefined) {
+            if (addr.region === _geoList[i].address.region)
+                select = true;
+            else
+                continue;
+        }
+
+        if (addr.county !== null && addr.county !== undefined) {
+            if (addr.county === _geoList[i].address.county)
+                select = true;
+            else
+                continue;
+        }
+
+        if (addr.city !== null && addr.city !== undefined) {
+            if (addr.city === _geoList[i].address.city)
+                select = true;
+            else
+                continue;
+        }
+
+        if (addr.street !== null && addr.street !== undefined) {
+            if (addr.street === _geoList[i].address.street)
+                select = true;
+            else
+                continue;
+        }
+
+        if (addr.streetNumber !== null && addr.streetNumber !== undefined) {
+            if (addr.streetNumber === _geoList[i].address.streetNumber)
+                select = true;
+            else
+                continue;
+        }
+
+        if (addr.premises !== null && addr.premises !== undefined) {
+            if (addr.premises === _geoList[i].address.premises)
+                select = true;
+            else
+                continue;
+        }
+
+        if (addr.additionalInformation !== null && 
+            addr.additionalInformation !== undefined) {
+            if (addr.additionalInformation === _geoList[i].address.additionalInformation)
+                select = true;
+            else
+                continue;
+        }
+
+        if (addr.postalCode !== null && addr.postalCode !== undefined) {
+            if (addr.postalCode === _geoList[i].address.postalCode)
+                select = true;
+            else
+                continue;
+        }
+
+        if (select === true) {
+            array.push(new GeocodeResult(_geoList[i].coordinate.latitude, _geoList[i].coordinate.longitude));
+        }
+    }
+
+    return array;
+}
+
+function _geocodeByAddress(address, successCB, errorCB, options) {
+    var array;
+    array = _findCoordsByAddress(address);
+    successCB(array);
+}
+
+function _checkAddressType(address) {
+    var str;
+    if (typeof address === "string") {
+        str = "string";
+    } else if (typeof address === "object") {
+        str = "StructuredAddress";
+    } else {
+        str = "typeMismatch";
+    }
+    return str;
+}
+
+function _checkCoordsType(coord) {
+    var str;
+    /* SimpleCoordinates is a subset of GeoCoordinates.
+       SimpleCoordinates includes latitude, longitude as mandatory fields only.
+       GeoCoordinates not only includes latitude, longitude as mandatory fields 
+       but also at least includes one more other optional fields */
+    if (typeof coord !== "object") {
+        str = "typeMismatch";
+    } else if (typeof coord.latitude === "number" &&
+                typeof coord.longitude === "number") {
+        str = "simpleCoordinates";
+        if (typeof coord.altitude === "number" ||
+            typeof coord.accuracy === "number" ||
+            typeof coord.altitudeAccuracy === "number" ||
+            typeof coord.heading === "number" ||
+            typeof coord.speed === "number") {
+            str = "geoCoordinates";
+        }
+    } else {
+        str = "typeMismatch";
+    }
+
+    return str;
+}
+
+function _findReverseGeocode(coords, options) {
+    var array = [], _isStructured = false, i;
+    if (options !== null && options !== undefined) {
+        if (options.resultType === "STRUCTURED") {
+            _isStructured = true;
+        }
+    }
+    for (i = 0; i < _geoList.length; i++) {
+        if (_geoList[i].coordinate.latitude === coords.latitude &&
+            _geoList[i].coordinate.longitude === coords.longitude) {
+            if (coords.altitude) {
+                if (_geoList[i].coordinate.altitude !== coords.altitude)
+                    continue;
+            }
+            if (coords.accuracy) {
+                if (_geoList[i].coordinate.accuracy !== coords.accuracy)
+                    continue;
+            }
+            if (coords.altitudeAccuracy) {
+                if (_geoList[i].coordinate.altitudeAccuracy !== coords.altitudeAccuracy)
+                    continue;
+            }
+            if (coords.heading) {
+                if (_geoList[i].coordinate.heading !== coords.heading)
+                    continue;
+            }
+            if (coords.speed) {
+                if (_geoList[i].coordinate.speed !== coords.speed)
+                    continue;
+            }
+
+            if (_isStructured === true) {
+                array.push(new lbs.StructuredAddress(_geoList[i].address));
+            } else {
+                array.push(_transAddressStr(_geoList[i].address));
+            }
+        }
+    }
+    return array;
+}
+
+function _reverseGeocodeByGeo(coordinates, successCB, errorCB, options) {
+    var array, coord;
+    coord = new lbs.GeoCoordinates(coordinates);
+    array = _findReverseGeocode(coord, options);
+    return successCB(array);
+}
+
+function _reverseGeocodeBySimple(coordinates, successCB, errorCB, options) {
+    var array, coord;
+    coord = new lbs.GeoCoordinates({
+            latitude : coordinates.latitude,
+            longitude : coordinates.longitude
+        });
+    array = _findReverseGeocode(coord, options);
+    return successCB(array);
+}
+
+module.exports = function (prop) {
+    var _self = new lbs.LocationServiceProvider(prop);
+    _geoList_init();
+    
+    _self.geocode = function (address, successCB, errorCB, options) {
+        function _geocode() {
+            var ret;
+        
+            ret = _pendingOperate(function () {
+                /* address: its type is AbstractAddress. 
+                   It could be StructuredAddress or String */
+                if (_checkAddressType(address) === "string") {
+                    _geocodeByString(address, successCB, errorCB, options);
+                } else if (_checkAddressType(address) === "StructuredAddress") {
+                    _geocodeByAddress(address, successCB, errorCB, options);
+                } else {
+                    throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+                }
+            });
+        }
+
+        tizen1_utils.validateTypeMismatch(successCB, errorCB, "geocode", _geocode); 
+    };
+
+    _self.reverseGeocode = function (coordinates, successCB, errorCB, options) {
+        function _reverseGeocode() {
+            var ret;
+            
+            ret = _pendingOperate(function () {
+                /* coordinates: Its type is AbstractCoordinates.
+                   It could be SimpleCoordinates or GeoCoordinates */
+                if (_checkCoordsType(coordinates) === "simpleCoordinates") {
+                    _reverseGeocodeBySimple(coordinates, successCB, errorCB, options);
+                } else if (_checkCoordsType(coordinates) === "geoCoordinates") {
+                    _reverseGeocodeByGeo(coordinates, successCB, errorCB, options);
+                } else {
+                    throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+                }
+            });
+        }
+
+        tizen1_utils.validateTypeMismatch(successCB, errorCB, "reverseGeocode", _reverseGeocode);
+    };
+
+    return _self;
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/ContactAnniversary', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+var tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError');
+
+module.exports = function (date, label) {
+    var _self, _date,
+        _label = null;
+
+    if (tizen1_utils.isValidDate(date)) {
+        _date = new Date(date);
+    } else {
+        throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+    }
+
+    if (label) {
+        _label = String(label);
+    }
+
+    _self = {
+        date : _date,
+        label : _label
+    };
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/AlarmRelative', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var AlarmBase = require('ripple/platform/tizen/1.0/AlarmBase');
+
+module.exports = function (delay, period) {
+    var alarm, date;
+
+    alarm  = new AlarmBase();
+    delay  = delay || 0;
+    period = period || null;
+    date   = new Date(); // Alarm settime
+
+    alarm.getRemainingSeconds = function () {
+        var current, diff, triggerDate, MILLI_SECOND = 1000;
+        current     = new Date();
+        triggerDate = new Date(delay * MILLI_SECOND + date.getTime()); // First triggerDate
+        diff        = Math.round((triggerDate - current) / MILLI_SECOND);
+
+        if (diff > 0) // Before first trigger
+            return diff;
+
+        if (period === null)
+            return null; // Alarm is expired
+
+        while (current - triggerDate >= 0) { // Trigger repeatly
+            triggerDate = new Date(period * MILLI_SECOND + triggerDate.getTime());
+        }
+        diff = Math.round(((triggerDate - current) / MILLI_SECOND));
+        return diff;
+    };
+
+    alarm.__defineGetter__("delay", function () {
+        return delay;
+    });
+    alarm.__defineGetter__("period", function () {
+        return period;
+    });
+    alarm.__defineGetter__("date", function () {
+        return date;
+    });
+    alarm.__defineSetter__("date", function (_date) {
+        date = new Date(_date);
+    });
+
+    return alarm;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/SortMode', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+var errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError');
+
+module.exports = function (_attributeName, _order) {
+    var _self;
+    if (_attributeName !== null && _attributeName !== undefined) {
+        if (typeof _attributeName !== "string") {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+    }
+    if (_order !== null && _order !== undefined) {
+        if (_order !== "ASC" && _order !== "DESC") {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+    }
+    _self = {
+        attributeName: _attributeName,
+        order: _order,
+    };
+
+    return _self;
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/AlarmAbsolute', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    AlarmBase = require('ripple/platform/tizen/1.0/AlarmBase'),
+    _byDayValue = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"],
+    PERIOD_WEEK = (7 * 24 * 60 * 60), MILLI_SECOND = 1000;
+
+module.exports = function (date, frequency) {
+    var alarm, period = null, daysOfTheWeek = [], ascDays = [];
+
+    function checkDayValue(days) {
+        var isDayType = false, i;
+        for (i in days) {
+            isDayType = utils.arrayContains(_byDayValue, days[i]);
+            if (!isDayType)
+                throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
+        }
+        return days;
+    }
+
+    function getScheduleDateByPeriod(current, date, period) {
+        var diff = period * MILLI_SECOND,
+            triggerDate = new Date(date);
+
+        while (current > (triggerDate - MILLI_SECOND)) { // In advance 1s - MILLI_SECOND
+            triggerDate.setTime(triggerDate.getTime() + diff);
+        }
+        return triggerDate;
+    }
+
+    function getSchedulteDateByDay(current, triggerTime, startDay, endDay) {
+        startDay = (7 + (endDay - startDay)) % 7;
+        current.setHours(triggerTime.getHours());
+        current.setMinutes(triggerTime.getMinutes());
+        current.setSeconds(triggerTime.getSeconds());
+        current.setMilliseconds(triggerTime.getMilliseconds());
+        current.setDate(current.getDate() + startDay);
+        return current;
+    }
+
+    function getAscDays() { // Get asc order array
+        for (var i in daysOfTheWeek) {
+            ascDays.push(_byDayValue.lastIndexOf(daysOfTheWeek[i]));
+        }
+        return ascDays.sort();
+    }
+
+    /*
+     * Return
+     *     true:  A is bigger than B
+     *     false: otherwise
+     */
+    function compareTime(current, triggerTime) {
+        var diff = current.getHours() - triggerTime.getHours();
+        if (diff !== 0)
+            return (diff > 0);
+
+        diff = current.getMinutes() - triggerTime.getMinutes();
+        if (diff !== 0)
+            return (diff > 0);
+
+        diff = current.getSeconds() - triggerTime.getSeconds();
+        if (diff < -1) // Delay 1s
+            return false;
+
+        return true;
+    }
+
+    alarm = new AlarmBase();
+    date = new Date(date);
+    if (frequency !== undefined) {
+        if (tizen1_utils.isValidArray(frequency)) {
+            daysOfTheWeek = checkDayValue(frequency);
+            if (daysOfTheWeek.length !== 0) {
+                period = PERIOD_WEEK;
+            }
+        } else {
+            period = frequency;
+        }
+    }
+
+    alarm.getNextScheduledDate = function () {
+        var current = new Date(),
+            diff, isPass, today, total, i, nextDate;
+
+        diff = current - date;
+        if (diff < -1000) // Advance 1s
+            return date; // Before first trigger, return date
+
+        if (period === null)
+            return null;
+
+        if (period !== PERIOD_WEEK)
+            return getScheduleDateByPeriod(current, date, period); // Repeat by period
+
+        today = current.getDay(); // 0~6
+        ascDays = getAscDays();
+        total = ascDays.length;
+
+        if ((ascDays[0] <= today) && (today <= ascDays[total - 1])) { // Today out of ascDays
+            for (i in ascDays) { // Today in ascDays
+                if (ascDays[i] < today) {
+                    continue;
+                } else if (ascDays[i] > today) {
+                    nextDate = ascDays[i];
+                    break;
+                } else {
+                    isPass = compareTime(current, date); // Is triggerTime pass
+                    if (isPass) {
+                        nextDate = ascDays[(i < total - 1) ? (parseInt(i, 10) + 1) : 0];
+                    } else {
+                        nextDate = today;
+                    }
+                    break;
+                }
+            }
+        } else {
+            nextDate = ascDays[0];
+        }
+
+        return getSchedulteDateByDay(current, date, today, nextDate);
+    };
+
+    alarm.__defineGetter__("date", function () {
+        return date;
+    });
+    alarm.__defineGetter__("period", function () {
+        return period;
+    });
+    alarm.__defineGetter__("daysOfTheWeek", function () {
+        return daysOfTheWeek;
+    });
+
+    return alarm;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/sensors', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    sensors = require('ripple/platform/tizen/1.0/spec/sensor'),
+    _sensors = ["Accelerometer", "MagneticField", "Rotation", "Orientation"],
+    _permission = true,    
+    _isWriteable = false, 
+    _self;
+
+function SensorError(code, msg) {
+    this.__defineGetter__("message", function () {
+        return msg;
+    });
+    this.__defineGetter__("code", function () {
+        return code;
+    });
+
+    this.PERMISSION_DENIED = -100;
+}
+
+function SensorRequest() {
+    var _self = {
+        result: [],
+        error: null,
+        readyState: "processing"        
+    };
+
+    this.__defineGetter__("result", function () {
+        return _self.result;
+    });
+    this.__defineSetter__("result", function (resultData) { 
+        if (_isWriteable) {
+            _self.result = utils.copy(resultData);
+            _isWriteable = false;
+            return;
+        }
+    });
+
+    this.__defineGetter__("error", function () {
+        return _self.error;
+    });
+    this.__defineSetter__("error", function (errorData) { 
+        if (_isWriteable) {
+            _self.error = utils.copy(errorData);
+            _isWriteable = false;
+            return;
+        }
+    });
+
+    this.__defineGetter__("readyState", function () {
+        return _self.readyState;
+    });
+    this.__defineSetter__("readyState", function (readyStateData) { 
+        if (_isWriteable) {
+            _self.readyState = readyStateData;
+            _isWriteable = false;
+            return;
+        }
+    });
+}
+
+_self = {  
+    findSensors: function (type) {
+        var sensorRequest = new SensorRequest(), index, sensorName = "";
+
+        setTimeout(function () {
+            if (_permission) {
+                for (index = 0; index < _sensors.length; index++) {
+                    sensorName = _sensors[index]; 
+                    if (type === null || type === undefined || type === sensorName) {   
+                        _isWriteable = true;                                     
+                        sensorRequest.result.push(sensors[sensorName]);
+                    }
+                }
+
+                _isWriteable = true;    
+                sensorRequest.readyState = "done";
+
+                if (sensorRequest.onsuccess) {
+                    sensorRequest.onsuccess();
+                }
+            }
+            else {
+                // error event on the request with error code PERMISSION_DENIED must be fired.
+                sensorRequest.error = new SensorError(-100, "permission denied!");
+                if (sensorRequest.onerror) {
+                    sensorRequest.onerror();
+                }
+            }
+        }, 1);
+
+        return sensorRequest;
+    }
+};
+
+module.exports = _self;
+
+
+});
+require.define('ripple/platform/tizen/1.0/msg_utils', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    MessageBody = require('ripple/platform/tizen/1.0/MessageBody'),
+    _TIZEN_MESSAGE_DB_KEY = "tizen_db_messages",
+    MessageElement = function (_type, _id) {
+        return {
+            type: _type,
+            id: _id,
+            msg: {},
+            conv: {}
+        };
+    },
+
+    _conversationCount = function (msg, cid, rst) {
+        var old_time = new Date(0), t;
+
+        utils.forEach(msg.msg, function (o) {
+            if (o.priv.conversationId === cid &&
+                o.priv.messageStatus !== "DRAFT") {
+                rst.cnt += 1;
+                t = new Date(o.priv.timestamp);
+                if (t > old_time) {
+                    rst.lastid = o.priv.id;
+                    old_time = t;
+                }
+                if (o.isRead === false) {
+                    rst.unread++;
+                }
+            }
+        });
+    },
+
+    _updateConversation = function (msg, cid) {
+        var privConv = {}, lastm, rst = {};
+
+        rst.cnt = 0;
+        rst.unread = 0;
+        rst.lastid = "";
+        _conversationCount(msg, cid, rst);
+        if (rst.cnt === 0) {
+            if (msg.conv[cid] !== undefined) {
+                delete msg.conv[cid];
+            }
+            return;
+        }
+        lastm = msg.msg[rst.lastid];
+
+        privConv.id = cid;
+        privConv.type = msg.type;
+        privConv.timestamp = new Date(lastm.priv.timestamp);
+        privConv.messageCount = rst.cnt;
+        privConv.unreadMessages = rst.unread;
+        privConv.preview = lastm.body.plainBody;
+        privConv.subject = lastm.subject;
+        privConv.isRead = lastm.isRead;
+        privConv.from = lastm.priv.from;
+        privConv.to = lastm.to.slice(0);
+        privConv.cc = lastm.cc.slice(0);
+        privConv.bcc = lastm.bcc.slice(0);
+        privConv.lastMessageId = rst.lastid;
+        msg.conv[cid] = privConv;
+    };
+
+module.exports = {
+    conversationCount: _conversationCount,
+    setMsg: function (m, newm) {
+        if ((m.to === null) || (m.to === undefined)) {
+            newm.to = [];
+        } else {
+            if (tizen1_utils.isValidArray(m.to)) {
+                newm.to = m.to.slice(0);
+            } else {
+                return false;
+            }
+        }
+
+        if ((m.cc === null) || (m.cc === undefined)) {
+            newm.cc = [];
+        } else {
+            if (tizen1_utils.isValidArray(m.cc)) {
+                newm.cc = m.cc.slice(0);
+            } else {
+                return false;
+            }
+        }
+
+        if ((m.bcc === null) || (m.bcc === undefined)) {
+            newm.bcc = [];
+        } else {
+            if (tizen1_utils.isValidArray(m.bcc)) {
+                newm.bcc = m.bcc.slice(0);
+            } else {
+                return false;
+            }
+        }
+
+        if ((m.body === null) || (m.body === undefined)) {
+            if (m.htmlBody === null || m.htmlBody === undefined) {
+                m.htmlBody = "";
+            }
+            if (m.plainBody === null || m.plainBody === undefined) {
+                m.plainBody = "";
+            }
+            if (typeof m.plainBody !== 'string' || typeof m.htmlBody !== 'string') {
+                return false;
+            }
+            m.body = new MessageBody(null, true, m.plainBody, m.htmlBody, []);
+        } else {
+            if (typeof m.body.plainBody !== 'string' || typeof m.body.htmlBody !== 'string') {
+                return false;
+            }
+            m.body = new MessageBody(null, true, m.body.plainBody, m.body.htmlBody, []);
+        }
+        newm.body = utils.copy(m.body);
+
+        if (typeof m.isRead === 'boolean') {
+            newm.isRead = m.isRead;
+        } else {
+            newm.isRead = false;
+        }
+
+        if (typeof m.isHighPriority === 'boolean') {
+            newm.isHighPriority = m.isHighPriority;
+        } else {
+            newm.isHighPriority = false;
+        }
+
+        if ((m.subject === null) || (m.subject === undefined)) {
+            newm.subject = "";
+        } else {
+            newm.subject = String(m.subject);
+        }
+
+        if ((m.inResponseTo === null) || (m.inResponseTo === undefined)) {
+            newm.inResponseTo = null;
+        } else {
+            newm.inResponseTo = String(m.inResponseTo);
+        }
+
+        if ((m.attachments === null) || (m.attachments === undefined)) {
+            newm.attachments = [];
+        } else {
+            newm.attachments = utils.copy(m.attachments);
+        }
+        return true;
+    },
+
+    loadMsg: function (type, id) {
+        var i, ret, msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || null;
+        if (msg === null) {
+            ret = new MessageElement(type, id);
+        } else {
+            for (i = 0; i < msg.length; i++) {
+                if (msg[i].type === type && msg[i].id === id) {
+                    ret = msg[i];
+                    break;
+                }
+            }
+            if (ret === undefined) {
+                ret = new MessageElement(type, id);
+            } else {
+                /* after getting Date out of DB, Date will become
+                   a string, so need to recast it back to Date */
+                for (i in ret.msg) {
+                    ret.msg[i].priv.timestamp = new Date(ret.msg[i].priv.timestamp);
+                }
+            }
+        }
+        return ret;
+    },
+
+    delMsg: function (m) { // m is a PrivMessage
+        var i, _msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || [];
+        if (_msg.length === 0) {
+            return;
+        } else {
+            for (i = 0; i < _msg.length; i++) {
+                if (_msg[i].type === m.priv.type && _msg[i].id === m.priv.serviceId) {
+                    delete _msg[i].msg[m.priv.id];
+                    if (m.priv.messageStatus !== "DRAFT") {
+                        _updateConversation(_msg[i], m.priv.conversationId);
+                    }
+                    db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg);
+                    return;
+                }
+            }
+        }
+    },
+
+    saveMsg: function (m) { // m is a PrivMessage
+        var i, new_msg, _msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || [];
+        if (_msg.length === 0) {
+            _msg = new MessageElement(m.priv.type, m.priv.serviceId);
+            _msg.msg[m.priv.id] = m;
+            if (m.priv.messageStatus !== "DRAFT") {
+                _updateConversation(_msg, m.priv.conversationId);
+            }
+            db.saveObject(_TIZEN_MESSAGE_DB_KEY, [_msg]);
+        } else {
+            for (i = 0; i < _msg.length; i++) {
+                if (_msg[i].type === m.priv.type && _msg[i].id === m.priv.serviceId) {
+                    _msg[i].msg[m.priv.id] = m;
+                    if (m.priv.messageStatus !== "DRAFT") {
+                        _updateConversation(_msg[i], m.priv.conversationId);
+                    }
+                    db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg);
+                    break;
+                }
+            }
+            if (i === _msg.length) {
+                new_msg = new MessageElement(m.priv.type, m.priv.serviceId);
+                new_msg.msg[m.priv.id] = m;
+                if (m.priv.messageStatus !== "DRAFT") {
+                    _updateConversation(new_msg, m.priv.conversationId);
+                }
+                _msg.push(new_msg);
+                db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg);
+            }
+        }
+    },
+
+    loadConv: function (type, id) {
+        var i, ret;
+        ret = this.loadMsg(type, id).conv;
+        for (i in ret) {
+            ret[i].timestamp = new Date(ret[i].timestamp);
+        }
+        return ret;
+    }
+};
+
+});
+require.define('ripple/platform/tizen/1.0/routeBackend_local', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    SimpleCoordinates = require('ripple/platform/tizen/1.0/SimpleCoordinates'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    lbs = require('ripple/platform/tizen/1.0/lbs'),
+    LocationServiceProvider = {},
+    RouteWaypoint,
+    RouteDistance,
+    RouteDuration,
+    RouteStep,
+    RouteSegment,
+    RouteRequestOptions,
+    RouteResultSummary,
+    RouteResult,
+    _data = {
+        DB_ROUTE_LOCATION_KEY: "tizen1-db-route",
+        DB_ROUTE_COLLEAGE_KEY: "tizen2-db-route",
+        routeProvider: {},
+        routes: [],
+        RouteDistanceUnit: ["M", "KM", "MI", "FT"],
+        providers: [],
+        path: []
+    },
+    _self;
+
+// The RouteWaypoint object
+RouteWaypoint = function () {
+    return {
+        position: {
+            latitude: 0,
+            longitude: 0
+        },
+        isStopover: true
+    };
+};
+
+// The RouteDistance object
+RouteDistance = function () {
+    return {
+        text: "",
+        value: 0,
+        unit: "KM"
+    };
+};
+
+// The RouteDuration object
+RouteDuration = function () {
+    return {
+        text: "",
+        value: 0 // The duration in a seconds
+    };
+};
+
+// The RouteStep object
+RouteStep = function () {
+    var _self = {
+        mode: "",        // The way of the travel, for example: car, bike, foot
+        instruction: "", // The instruction of this step
+        points: []       // The points of this step
+    };
+
+    _self.origin      = new SimpleCoordinates(0, 0);
+    _self.destination = new SimpleCoordinates(0, 0);
+    _self.distance    = new RouteDistance();
+    _self.duration    = new RouteDuration();
+
+    return _self;
+};
+
+// The RouteSegment object
+RouteSegment = function () {
+    var _self = {
+        steps: []
+    };
+
+    _self.origin      = new SimpleCoordinates(0, 0);
+    _self.destination = new SimpleCoordinates(0, 0);
+    _self.distance    = new RouteDistance();
+    _self.duration    = new RouteDuration();
+
+    return _self;
+};
+
+// The RouteRequestOptions object
+RouteRequestOptions = function () {
+    return {
+        mode: "", // CAR, BIKE
+        unit: "KM",
+        routeGoal: "SHORTEST",
+        constraints: ["HIGHWAY", "TOLL", "UNPAVED"],
+        wayPoints: [],
+        maxResults: 1
+    };
+};
+
+// The RouteResultSummary object
+RouteResultSummary = function () {
+    var _self = {};
+
+    _self.origin        = new SimpleCoordinates(0, 0);
+    _self.destination   = new SimpleCoordinates(0, 0);
+    _self.totalDistance = new RouteDistance();
+    _self.totalDuration = new RouteDuration();
+
+    return _self;
+};
+
+// The RouteResult object
+RouteResult = function () {
+    var _self = {
+        segments: []
+    };
+
+    _self.summary = new RouteResultSummary();
+
+    return _self;
+};
+
+// Floyd arithmetic in Mathematics, solving the optimal way
+function floyd(e, n, startIndex, endIndex) {
+    var MAX = Infinity,
+        a = new Array(n), i, j, k, p = new Array(n),
+        paths, pathWay = [];
+
+    for (i = 1; i < n + 1; i++) {
+        a[i] = new Array(n);
+    }
+    for (i = 1; i < n + 1; i++) {
+        p[i] = new Array(n);
+    }
+    for (i = 1; i < n + 1; i++) {
+        for (j = 1; j < n + 1; j++) {
+            if (i === j || e[i][j] === "MIN") {
+                a[i][j] = 0;
+            } else if (e[i][j] !== 0 && e[i][j] !== "MIN") {
+                a[i][j] = e[i][j];
+            } else {
+                a[i][j] = MAX;
+            }
+            p[i][j] = 0;
+        }
+    }
+    for (i = 1; i < n + 1; i++) {
+        a[i][i] = 0;
+    }
+    for (k = 1; k < n + 1; k++) {
+        for (i = 1; i < n + 1; i++) {
+            for (j = 1; j < n + 1; j++) {
+                if (parseInt(a[i][k], 10) + parseInt(a[k][j], 10) < a[i][j]) {
+                    a[i][j] = parseInt(a[i][k], 10) + parseInt(a[k][j], 10);
+                    p[i][j] = k;
+                }
+            }
+        }
+    }
+    _data.path = [];
+    paths = findPath(startIndex, endIndex, p);
+    pathWay = [];
+    pathWay.push(startIndex);
+    for (i = 0; i < paths.length; i++) {
+        pathWay.push(paths[i]);
+    }
+    pathWay.push(endIndex);
+
+    return pathWay;
+}
+
+// Find the best way in the locations
+function findPath(i, j, p) {
+    var k = p[i][j];
+
+    if (k === 0 || i === j) {
+        return _data.path;
+    }
+    findPath(i, k, p);
+    _data.path.push(k);
+
+    return findPath(k, j, p);
+}
+
+// Find the index in the locations by string
+function findIndexByStr(str, locations) {
+    for (var i in locations) {
+        if (locations[i].name === str) {
+            return parseInt(i, 10) + 1;
+        }
+    }
+    return -1;
+}
+
+// Find the index in the colleages by name1 and name2
+function findValueByStr(start, end, locations, colleages) {
+    for (var i in colleages) {
+        if (colleages[i].name1 === locations[start - 1].name && colleages[i].name2 === locations[end - 1].name) {
+            return parseInt(i, 10);
+        } else if (colleages[i].name2 === locations[start - 1].name && colleages[i].name1 === locations[end - 1].name) {
+            return parseInt(i, 10);
+        }
+    }
+    return -1;
+}
+
+// Find the index in the locations by latitude and longitude
+function searchIndexBycoodinates(latitude, longitude, locations) {
+    if (latitude !== null && longitude !== null) {
+        for (var i in locations) {
+            if (locations[i].latitude === latitude && locations[i].longitude === longitude) {
+                return parseInt(i, 10) + 1;
+            }
+        }
+    }
+    return -1;
+}
+
+// Get the relation among the locations
+function getRelation(n, colleages, locations, goal) {
+    var i, j, start, end, relation = new Array(n + 1);
+    for (i = 1; i < n + 2; i++) {
+        relation[i] = new Array(n + 1);
+    }
+    for (i = 1; i < n + 1; i++) {
+        for (j = 1; j < n + 1; j++) {
+            relation[i][j] = 0;
+        }
+    }
+    for (i in colleages) {
+        start = findIndexByStr(colleages[i].name1, locations);
+        end = findIndexByStr(colleages[i].name2, locations);
+        if (start !== -1 && end !== -1 && start !== end) {
+            switch (goal) {
+            case "distance":
+                relation[start][end] = colleages[i].distance;
+                relation[end][start] = colleages[i].distance;
+                break;
+
+            case "duration":
+                relation[start][end] = colleages[i].duration;
+                relation[end][start] = colleages[i].duration;
+                break;
+
+            case "simple":
+                relation[start][end] = 1;
+                relation[end][start] = 1;
+                break;
+
+            case "scenic":
+                if (colleages[i].addition.scenic === "SCENIC") {
+                    relation[start][end] = 1;
+                    relation[start][end] = 1;
+                } else if (colleages[i].addition.scenic === "") {
+                    relation[start][end] = "MIN";
+                    relation[start][end] = "MIN";
+                }
+                break;
+
+            case "cheap":
+                if (colleages[i].addition.toll === "TOLL") {
+                    relation[start][end] = 1;
+                    relation[end][start] = 1;
+                } else if (colleages[i].addition.toll === "") {
+                    relation[start][end] = "MIN";
+                    relation[start][end] = "MIN";
+                }
+                break;
+
+            case "safe":
+                if (colleages[i].addition.hazardous === "HAZARDOUS") {
+                    relation[start][end] = 1;
+                    relation[end][start] = 1;
+                } else if (colleages[i].addition.hazardous === "") {
+                    relation[start][end] = "MIN";
+                    relation[end][start] = "MIN";
+                }
+                break;
+
+            default:
+                return null;
+            }
+        }
+    }
+
+    return relation;
+}
+
+// Get the distance relationship among the locations
+function distanceRelation(n, colleages, locations) {
+    return getRelation(n, colleages, locations, "distance");
+}
+
+// Get the duration relationship among the locations
+function durationRelation(n, colleages, locations) {
+    return getRelation(n, colleages, locations, "duration");
+}
+
+// Get the simple relationship among the locations
+function simpleRelation(n, colleages, locations) {
+    return getRelation(n, colleages, locations, "simple");
+}
+
+// Get the cheap relationship among the locations
+function cheapRelation(n, colleages, locations) {
+    return getRelation(n, colleages, locations, "cheap");
+}
+
+// Get the safe relationship among the locations
+function safeRelation(n, colleages, locations) {
+    return getRelation(n, colleages, locations, "safe");
+}
+
+// Get the scenic relationship among the locations
+function scenicRelation(n, colleages, locations) {
+    return getRelation(n, colleages, locations, "scenic");
+}
+
+// Get the shortest way by origin, destination, locations and colleages
+function optimalWay(origin, destination, locations, colleages, relation) {
+    var n = locations.length, i, steps = [], step, relations, routeLocations,
+        originIndex, destinationIndex, startIndex, endIndex, colleageIndex,
+        originLatitude, originLongitude, destinationLatitude, destinationLongitude,
+        startLatitude, startLongitude, endLatitude, endLongitude,
+        originLocation, destinationLocation, segment, result;
+
+    originLatitude = origin.latitude;
+    originLongitude = origin.longitude;
+    originIndex = searchIndexBycoodinates(originLatitude, originLongitude, locations);
+
+    destinationLatitude = destination.latitude;
+    destinationLongitude = destination.longitude;
+    destinationIndex = searchIndexBycoodinates(destinationLatitude, destinationLongitude, locations);
+
+    relations = relation(n, colleages, locations);
+
+    if (originIndex !== -1 && destinationIndex !== -1) {
+        routeLocations = floyd(relations, n, parseInt(originIndex, 10), parseInt(destinationIndex, 10));
+
+        for (i = 0; i < routeLocations.length - 1; i++) {
+            colleageIndex = findValueByStr(routeLocations[i], routeLocations[i + 1], locations, colleages);
+
+            if (colleageIndex !== -1) {
+                step = new RouteStep();
+                startIndex = parseInt(routeLocations[i], 10) - 1;
+                endIndex = parseInt(routeLocations[i + 1], 10) - 1;
+
+                startLatitude = locations[startIndex].latitude;
+                startLongitude = locations[startIndex].longitude;
+                originLocation = new SimpleCoordinates(startLatitude, startLongitude);
+
+                endLatitude = locations[endIndex].latitude;
+                endLongitude = locations[endIndex].longitude;
+                destinationLocation = new SimpleCoordinates(endLatitude, endLongitude);
+
+                step.origin = originLocation;
+                step.destination = destinationLocation;
+                step.distance = colleages[colleageIndex].distance;
+                step.duration = colleages[colleageIndex].duration;
+                step.mode = colleages[colleageIndex].mode;
+                step.addition = colleages[colleageIndex].addition;
+
+                steps.push(step);
+            } else if (colleageIndex === -1) {
+                return null;
+            }
+        }
+
+        segment = new RouteSegment();
+        segment.steps = steps;
+        result = new RouteResult();
+        result.segments[0] = segment;
+
+        return result;
+    }
+    return null;
+}
+
+// Get the shortest way by origin, destination, locations and colleages
+function shortestWay(origin, destination, locations, colleages) {
+    return optimalWay(origin, destination, locations, colleages, distanceRelation);
+}
+
+// Get the fastest way by origin, destination, locations and colleages
+function fastestWay(origin, destination, locations, colleages) {
+    return optimalWay(origin, destination, locations, colleages, durationRelation);
+}
+
+// Get the simplest way by origin, destination, locations and colleages
+function simplestWay(origin, destination, locations, colleages) {
+    return optimalWay(origin, destination, locations, colleages, simpleRelation);
+}
+
+// Get the most scenic way by origin, destination, locations and colleages
+function mostScenicWay(origin, destination, locations, colleages) {
+    return optimalWay(origin, destination, locations, colleages, scenicRelation);
+}
+
+// Get the cheapest way by origin, destination, locations and colleages
+function cheapestWay(origin, destination, locations, colleages) {
+    return optimalWay(origin, destination, locations, colleages, cheapRelation);
+}
+
+// Get the safest way by origin, destination, locations and colleages
+function safestWay(origin, destination, locations, colleages) {
+    return optimalWay(origin, destination, locations, colleages, safeRelation);
+}
+
+// Uniquelize the array
+function uniquelize(array) {
+    var temp = {}, result = [], i;
+    for (i = array.length; i--;) {
+        temp[array[i]] = array[i];
+    }
+    for (i in temp) {
+        result.push(temp[i]);
+    }
+    return result;
+}
+
+// Is it intersect between the Array a and b
+function intersect(a, b) {
+    var i, j;
+
+    a = uniquelize(a);
+    if (a.length === 0 && b.length === 0) {
+        return true;
+    }
+    for (i in a) {
+        for (j in b) {
+            if (a[i] === b[j])
+                return true;
+        }
+    }
+    return false;
+}
+
+function getConstrains(result) {
+    var steps = result.segments[0].steps, constrains = [];
+
+    utils.forEach(steps, function (item, index) {
+        if (item.addition.highway === "HIGHWAY") {
+            constrains.push("HIGHWAY");
+        }
+        if (item.addition.toll === "TOLL") {
+            constrains.push("TOLL");
+        }
+        if (item.addition.bridge === "BRIDGE") {
+            constrains.push("BRIDGE");
+        }
+        if (item.addition.hazardous === "HAZARDOUS") {
+            constrains.push("HAZARDOUS");
+        }
+        if (item.addition.scenic === "SCENIC") {
+            constrains.push("SCENIC");
+        }
+    });
+    if (constrains.length > 0) {
+        return uniquelize(constrains);
+    }
+    return constrains;
+}
+
+module.exports = function (prop) {
+    var _self = new lbs.LocationServiceProvider(prop);
+    _self.find = function (origin, destination, successCallback, errorCallback, options) {
+        function _find() {
+            var locations, colleages, i, result = {}, emptyResult = [], modes = [], resultModes = [], constrains = [], resultconstrains = [];
+
+            locations = db.retrieveObject(_data.DB_ROUTE_LOCATION_KEY);
+            colleages = db.retrieveObject(_data.DB_ROUTE_COLLEAGE_KEY);
+
+            modes = options.modes;
+            constrains = options.constrains;
+            if (locations.length > 0 && colleages.length > 0) {
+                switch (options.routeGoal) {
+                case "SHORTEST":
+                    result = shortestWay(origin, destination, locations, colleages);
+                    break;
+
+                case "FASTEST":
+                    result = fastestWay(origin, destination, locations, colleages);
+                    break;
+
+                case "SIMPLEST":
+                    result = simplestWay(origin, destination, locations, colleages);
+                    break;
+
+                case "MOST_SCENIC":
+                    result = mostScenicWay(origin, destination, locations, colleages);
+                    break;
+
+                case "CHEAPEST":
+                    result = cheapestWay(origin, destination, locations, colleages);
+                    break;
+
+                case "SAFEST":
+                    result = safestWay(origin, destination, locations, colleages);
+                    break;
+
+                default:
+                    result = shortestWay(origin, destination, locations, colleages);
+                    break;
+                }
+                if (result !== null) {
+                    for (i in result.segments[0].steps) {
+                        resultModes.push(result.segments[0].steps[i].mode);
+                    }
+                    resultconstrains = getConstrains(result);
+                    if (intersect(resultModes, modes) && intersect(resultconstrains, constrains)) {
+                        successCallback(result);
+                    } else {
+                        successCallback(null);
+                    }
+                }
+            } else {
+                successCallback(emptyResult);
+            }
+        }
+        tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find);
+    };
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/dbfs', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    _console = require('ripple/console'),
+    _cache = {},
+    _self;
+
+function _get(path) {
+    return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
+        return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
+    }, _cache);
+}
+
+function _getInfo(path) {
+    var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
+        name = parent.splice(parent.length - 1, 1).join("");
+
+    return {
+        name: name,
+        parent: parent.join("/") || "/"
+    };
+}
+
+function _set(path, obj) {
+    var parent = _cache,
+        tokens = path.replace(/^\//, '').split("/"),
+        child = tokens.splice(tokens.length - 1, 1).join("");
+
+    tokens.forEach(function (token) {
+        parent = parent.children[token];
+    });
+
+    parent.children = parent.children || {};
+    parent.children[child] = obj;
+}
+
+function _delete(path) {
+    var parent = _cache,
+        tokens = path.replace(/^\//, '').split("/"),
+        child = tokens.splice(tokens.length - 1, 1).join("");
+
+    tokens.forEach(function (token) {
+        parent = parent.children[token];
+    });
+
+    delete parent.children[child];
+}
+
+function _save() {
+    db.saveObject("tizen1-db-filesystem", _cache);
+}
+
+function _walk(path, parent) {
+    _self.ls(path, function (entries) {
+        parent.children = parent.children || {};
+
+        entries.forEach(function (entry) {
+            parent.children[entry.name] = entry;
+
+            if (entry.isDirectory) {
+                _walk(entry.fullPath, entry);
+            } else {
+                /* after getting Date out of DB, Date will become
+                   a string, so need to recast it back to Date */
+                if (entry.lastModifiedDate !== null && entry.lastModifiedDate !== undefined)
+                    entry.lastModifiedDate = new Date(entry.lastModifiedDate);
+
+                _self.read(entry.fullPath, function (data) {
+                    parent.children[entry.name].data = data;
+                }, function (e) {
+                    _console.error(e);
+                });
+            }
+        });
+    }, function (e) {
+        _console.error(e);
+    });
+}
+
+function _createPath(path) {
+    var parts = path.replace(/^\//, '').split("/"),
+        workflow = jWorkflow.order();
+
+    parts.forEach(function (part, index) {
+        var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/");
+
+        workflow.andThen(function (prev, baton) {
+            baton.take();
+            _self.mkdir(dir, baton.pass, baton.pass);
+        });
+    });
+
+    workflow.start();
+}
+
+_self = {
+    // The order is consistent with _virtualRoots in filesystem.js
+    roots: ["/opt/documents", "/opt/images", "/opt/music", "/opt/videos", "/opt/downloads", "/home/user/appdata/simulatedapp/wgt-package", "/home/user/appdata/simulatedapp/wgt-private", "/home/user/appdata/simulatedapp/wgt-private-tmp", "/SDCard", "/opt/attachments"],
+    initialize: function () {
+        // TODO: Initialize at bootstrap and emulatorBridge.link
+        _cache = db.retrieveObject("tizen1-db-filesystem") || {};
+        // create real root paths if empty
+        _self.roots.every(function (root) {
+            _createPath(root);
+            return true;
+        });
+       // build the file system cache so that we could access information synchronously
+        _walk("/", _cache);
+    },
+    ls: function (path, success, error) {
+        try {
+            var dir = _get(path),
+                items = [];
+
+            if (dir) {
+                utils.forEach(dir.children, function (item) {
+                    items.push(item);
+                });
+            }
+            else {
+                items = {};
+            }
+
+            success(items);
+        }
+        catch (e) {
+            e.code = 1;
+            error(e);
+        }
+    },
+    rm: function (path, success, error, options) {
+        _delete(path);
+        _save();
+        success();
+    },
+    rmdir: function (path, success, error, options) {
+        _delete(path);
+        _save();
+        success();
+    },
+    mkdir: function (path, success, error) {
+        var entry = _get(path),
+            info = _getInfo(path);
+
+        if (!entry) {
+            _set(path, {
+                name: info.name,
+                isDirectory: true,
+                fullPath: path
+            });
+            entry = _get(path);
+            _save();
+        }
+
+        if (entry) {
+            success(entry);
+        }
+        else {
+            error({code: 1});
+        }
+    },
+    mv: function (from, to, success, error) {
+        try {
+            var fromEntry = _get(from),
+                toInfo = _getInfo(to);
+
+            fromEntry.fullPath = to;
+            fromEntry.name = toInfo.name;
+
+            _set(to, fromEntry);
+            _delete(from);
+            _save();
+            success();
+        }
+        catch (e) {
+            e.code = 1;
+            error(e);
+        }
+    },
+    touch: function (path, success, error) {
+        var entry = _get(path),
+            info  = _getInfo(path);
+
+        if (!entry) {
+            _set(path, {
+                lastModifiedDate: new Date(),
+                name: info.name,
+                isDirectory: false,
+                fullPath: path,
+                data: ""
+            });
+            entry = _get(path);
+        }
+        _save();
+        success(entry);
+    },
+    cp: function (from, to, success, error) {
+        try {
+            var fromEntry = _get(from),
+                copied = utils.copy(fromEntry);
+
+            copied.name  = _getInfo(to).name;
+            copied.fullPath = to;
+            _set(to, copied);
+            _save();
+            success();
+        }
+        catch (e) {
+            e.code = 1;
+            error(e);
+        }
+    },
+    stat: function (path, success, error) {
+        var entry = _get(path);
+
+        if (entry) {
+            success(entry);
+        } else {
+            error({code: 1});
+        }
+    },
+    write: function (path, contents, success, error, options) {
+        var entry = _get(path);
+
+        if (entry) {
+            entry.lastModifiedDate = new Date();
+            entry.data = contents;
+            _save();
+            success();
+        } else {
+            error({code: 1});
+        }
+
+    },
+    read: function (path, success, error) {
+        var entry = _get(path);
+
+        if (entry) {
+            success(utils.copy(entry.data));
+        }
+        else {
+            error({code: 1});
+        }
+    }
+};
+
+module.exports = _self;
+
+
+});
+require.define('ripple/platform/tizen/1.0/DeviceMotionEvent', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    Event = require('ripple/platform/tizen/1.0/EventBase');
+
+module.exports = function () {
+    var _self = {
+            acceleration: {
+                x: null,
+                y: null,
+                z: null
+            },
+            accelerationIncludingGravity: {
+                x: null,
+                y: null,
+                z: null
+            },
+            rotationRate: {
+                alpha: null,
+                beta: null,
+                gamma: null
+            },
+            interval: 0
+        };
+
+    Event.call(this);
+
+    this.__defineGetter__("acceleration", function () {
+        return _self.acceleration;
+    });
+
+    this.__defineGetter__("accelerationIncludingGravity", function () {
+        return _self.accelerationIncludingGravity;
+    });
+
+    this.__defineGetter__("rotationRate", function () {
+        return _self.rotationRate;
+    });
+
+    this.__defineGetter__("interval", function () {
+        return _self.interval;
+    });
+
+    this.initAccelerometerEvent = function (accelerometerType, accelerometerBubbles, accelerometerCancelable,
+                                            accelerationData, accelerationGData, rotationRateData, intervalValue) {
+        this.initEvent(accelerometerType, accelerometerBubbles, accelerometerCancelable);
+
+        _self.acceleration = utils.copy(accelerationData);
+        _self.accelerationIncludingGravity = utils.copy(accelerationGData);
+        _self.rotationRate = utils.copy(rotationRateData);
+        _self.interval = intervalValue;
+    };
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/GeocodeOptions', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var errorcode = require('ripple/platform/tizen/1.0/errorcode'),
+    WebAPIError = require('ripple/platform/tizen/1.0/WebAPIError'),
+    SortMode = require('ripple/platform/tizen/1.0/SortMode');
+
+module.exports = function (_sortMode, _maxResults) {
+    var _self;
+    if (_sortMode !== null && _sortMode !== undefined) {
+        if (typeof _sortMode !== "object") {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        try {
+            new SortMode(_sortMode.attributeName, _sortMode.order);
+        } catch (e) {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+    }
+    if (_maxResults !== null && _maxResults !== undefined) {
+        if (typeof _maxResults !== "number") {
+            throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
+        }
+    }
+
+    _self = {
+        sortMode : _sortMode,
+        maxResults : _maxResults || 0
+    };
+
+    return _self;
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/spec/sensor', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event');
+
+function sensorStatusEventTrigger(setting) {
+    event.trigger("SensorStatusChanged", [setting]);
+}
+
+module.exports = {
+    "Accelerometer": {
+        "resolution": 0.039239998906850815,
+        "minDelay": 20,
+        "range": 20.051639556884766,
+        "name": "Accelerometer",
+        "type": "Accelerometer"
+    },
+    "MagneticField": {
+        "x": {
+            "name": "X",
+            "control": {
+                "type": "range",
+                "value": 100.0000000000000000,
+                "min": 0.0000000000000000,
+                "max": 200.0000000000000000,
+                "step": 0.0000000000000001
+            },
+            "callback": function (setting) {
+                event.trigger("MagneticField-xChanged", [setting]);
+            }
+        },
+
+        "y": {
+            "name": "Y",
+            "control": {
+                "type": "range",
+                "value": 100.0000000000000000,
+                "min": 0.0000000000000000,
+                "max": 200.0000000000000000,
+                "step": 0.0000000000000001
+            },
+            "callback": function (setting) {
+                event.trigger("MagneticField-yChanged", [setting]);
+            }
+        },
+
+        "z": {
+            "name": "Z",
+            "control": {
+                "type": "range",
+                "value": 100.0000000000000000,
+                "min": 0.0000000000000000,
+                "max": 200.0000000000000000,
+                "step": 0.0000000000000001
+            },
+            "callback": function (setting) {
+                event.trigger("MagneticField-zChanged", [setting]);
+            }
+        },
+
+        "resolution": 1,
+        "minDelay": 20,
+        "range": 359,
+        "name": "MagneticField",
+        "type": "MagneticField"
+    },
+    "Rotation": {
+        "resolution": 1,
+        "minDelay": 20,
+        "range": 359,
+        "name": "Rotation",
+        "type": "Rotation"
+    },
+    "Orientation": {
+        "resolution": 1,
+        "minDelay": 20,
+        "range": 359,
+        "name": "Orientation",
+        "type": "Orientation"
+    }
+};
+
+});
+require.define('ripple/platform/tizen/1.0/spec/device', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    NetworkTypeTable = {
+        "NONE": "None",
+        "2G": "2G",
+        "2.5G": "2.5G",
+        "3G": "3G",
+        "4G": "4G",
+        "WIFI": "Wi-Fi",
+        "ETHERNET": "Ethernet",
+        "UNKNOWN": "Unknown"
+    };
+
+function deviceStatusEventTrigger(setting) {
+    event.trigger("DeviceStatusChanged", [setting]);
+}
+
+module.exports = {
+    "Config": {
+        "vibratingMode": {
+            "name": "Vibrator",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "callback": function (setting) {
+                event.trigger("VibratingModeChanged", [setting]);
+            }
+        },
+        "lockScreen": {
+            "name": "Lock Screen",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            },
+            "callback": function (setting) {
+                event.trigger("LockScreenChanged", [setting]);
+            }
+        }
+    },    
+    "Cpu": {
+        "load": {
+            "name": "Load",
+            "control": {
+                "type": "text",
+                "value": 0.1
+            },
+            "event": "CpuLoadChanged",
+            "callback": function (setting) {
+                event.trigger("CpuLoadChanged", [setting]);
+            }
+        }
+    },
+    "Storage": {
+        "units": {
+            "name": "Units",
+            "control": {
+                "type": "label",
+                "innertext": "INTERNAL",
+                "value": "INTERNAL"
+            },
+        }
+    },
+    "Display": {
+        "resolutionWidth": {
+            "name": "Resolution Width",
+            "control": {
+                "type": "label",
+                "innertext": 0,
+                "value": 0
+            }
+        }, 
+        "resolutionHeight": {
+            "name": "Resolution Height",
+            "control": {
+                "type": "label",
+                "value": 0
+            }
+        },     
+        "dotsPerInchWidth": {
+            "name": "DPI-X",
+            "control": {
+                "type": "label",
+                "value": 0
+            }
+        },     
+        "dotsPerInchHeight": {
+            "name": "DPI-Y",
+            "control": {
+                "type": "label",
+                "value": 0
+            }
+        },
+        "physicalWidth": {
+            "name": "Physical Width",
+            "control": {
+                "type": "label",
+                "value": 0
+            }
+        },
+        "physicalHeight": {
+            "name": "Physical Height",
+            "control": {
+                "type": "label",
+                "value": 0
+            }
+        },
+        "brightness": {
+            "name": "Brightness",
+            "control": {
+                "type": "number",
+                "value": 0.8,
+            },
+            "event": "DisplayBrightnessChanged",
+            "callback": function (setting) {
+                event.trigger("DisplayBrightnessChanged", [setting]);
+            }
+        }
+    },    
+    "Device": {
+        "imei": {
+            "name": "IMEI",
+            "control": {
+                "type": "label",
+                "value": "352099001761482"
+            }
+        }, 
+        "model": {
+            "name": "GT-TIZEN",
+            "control": {
+                "type": "label",
+                "value": ""
+            }
+        }, 
+        "version": {
+            "name": "Version",
+            "control": {
+                "type": "label",
+                "value": "TIZEN_1.0"
+            }
+        }, 
+        "vendor": {
+            "name": "Vendor",
+            "control": {
+                "type": "label",
+                "value": ""
+            }
+        }
+    },
+    "Network": {
+        "networkType": {
+            "name": "Network Type",
+            "control" : {
+                "type": "select",
+                "value": 0
+            },
+            "options": (function () {
+                var i,
+                    optionList = {};
+                utils.forEach(NetworkTypeTable, function(key, value) {
+                    optionList[key] = NetworkTypeTable[value];
+                });
+
+                return optionList;
+            }()),
+            "event": "NetworkTypeChanged",
+            "callback": function (setting) {
+                event.trigger("NetworkTypeChanged", [setting]);
+            }
+        }
+    },
+    "WifiNetwork": {
+        "status": {
+            "name": "Status",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            },
+            "event": "WiFiNetworkStatusChanged",
+            "callback": function (setting) {
+                event.trigger("WiFiNetworkStatusChanged", [setting]);
+            }
+        },
+        "ssid": {
+            "name": "SSID",
+            "control": {
+                "type": "text",
+                "value": "Tizen WiFi"
+            },
+            "event": "WiFiNetworkSSIDChanged",
+            "callback": function (setting) {
+                event.trigger("WiFiNetworkSSIDChanged", [setting]);
+            }
+        }, 
+        "ipAddress": {
+            "name": "IP Address",
+            "control": {
+                "type": "text",
+                "value": "192.168.0.1"
+            },
+            "event": "WiFiNetworkIpAddressChanged",
+            "callback": function (setting) {
+                event.trigger("WiFiNetworkIpAddressChanged", [setting]);
+            }
+        }, 
+        "signalStrength": {
+            "name": "Signal Strength",
+            "control": {
+                "type": "select",
+                "value": 0
+            },
+            "options": (function () {
+                var i,
+                    optionList = {};
+
+                for (i = 0; i <= 10; i++) {
+                    optionList[i] = i;
+                }
+
+                return optionList;
+            }()),
+            "event": "WiFiNetworkSignalStrengthChanged",
+            "callback": function (setting) {
+                event.trigger("WiFiNetworkSignalStrengthChanged", [setting]);
+            }
+        }
+    },
+    "CellularNetwork": {
+        "status": {
+            "name": "Status",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "event": "CellularNetworkStatusChanged",
+            "callback": function (setting) {
+                event.trigger("CellularNetworkStatusChanged", [setting]);
+            }
+        },
+        "apn": {
+            "name": "APN",
+            "control": {
+                "type": "text",
+                "value": "Tizen"
+            },
+            "event": "CellularNetworkapnChanged",
+            "callback": function (setting) {
+                event.trigger("CellularNetworkapnChanged", [setting]);
+            }
+        },
+        "ipAddress": {
+            "name": "IP Address",
+            "control": {
+                "type": "text",
+                "value": "10.0.2.16"
+            },
+            "event": "CellularNetworkipAddressChanged",
+            "callback": function (setting) {
+                event.trigger("CellularNetworkipAddressChanged", [setting]);
+            }
+        },         
+        "mcc": {
+            "name": "MCC",
+            "control": {
+                "type": "text",
+                "value": "460"
+            },
+            "event": "CellularNetworkmccChanged",
+            "callback": function (setting) {
+                event.trigger("CellularNetworkmccChanged", [setting]);
+            }
+        }, 
+        "mnc": {
+            "name": "MNC",
+            "control": {
+                "type": "text",
+                "value": "0"
+            },
+            "event": "CellularNetworkmncChanged",
+            "callback": function (setting) {
+                event.trigger("CellularNetworkmncChanged", [setting]);
+            }
+        }, 
+        "cellId": {
+            "name": "Cell ID",
+            "control": {
+                "type": "text",
+                "value": "0"
+            },
+            "event": "CellularNetworkcellIdChanged",
+            "callback": function (setting) {
+                event.trigger("CellularNetworkcellIdChanged", [setting]);
+            }
+        }, 
+        "lac": {
+            "name": "LAC",
+            "control": {
+                "type": "text",
+                "value": "0"
+            },
+            "event": "CellularNetworklacChanged",
+            "callback": function (setting) {
+                event.trigger("CellularNetworklacChanged", [setting]);
+            }
+        }, 
+        "serviceType": {
+            "name": "Service Type",
+            "control": {
+                "type": "text",
+                "value": "INTERNET"
+            },
+            "event": "CellularNetworkserviceTypeChanged",
+            "callback": function (setting) {
+                event.trigger("CellularNetworkserviceTypeChanged", [setting]);
+            }
+        }, 
+        "isRoaming": {
+            "name": "Roaming",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "event": "CellularNetworkIsInRoamingChanged",
+            "callback": function (setting) {
+                event.trigger("CellularNetworkIsInRoamingChanged", [setting]);
+            }
+        }
+    },
+    "EthernetNetwork": {
+        "status": {
+            "name": "Status",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            },
+            "event": "EthernetStatusChanged",
+            "callback": function (setting) {
+                event.trigger("EthernetStatusChanged", [setting]);
+            }
+        },
+        "ipAddress": {
+            "name": "IP Address",
+            "control": {
+                "type": "text",
+                "value": "192.168.0.1"
+            },
+            "event": "EthernetIpAddressChanged",
+            "callback": function (setting) {
+                event.trigger("EthernetIpAddressChanged", [setting]);
+            }
+        },
+        "ipv6Address": {
+            "name": "IPv6 Address",
+            "control": {
+                "type": "text",
+                "value": "192.168.0.1"
+            },
+            "event": "EthernetIpv6AddressChanged",
+            "callback": function (setting) {
+                event.trigger("EthernetIpv6AddressChanged", [setting]);
+            }
+        },
+        "proxyAddress": {
+            "name": "Proxy Address",
+            "control": {
+                "type": "text",
+                "value": "192.168.0.30"
+            },
+            "event": "EthernetProxyAddressChanged",
+            "callback": function (setting) {
+                event.trigger("EthernetProxyAddressChanged", [setting]);
+            }
+        },
+        "macAddress": {
+            "name": "MAC Address",
+            "control": {
+                "type": "text",
+                "value": "11:22:33:44:55:66"
+            },
+            "event": "EthernetMacAddressChanged",
+            "callback": function (setting) {
+                event.trigger("EthernetMacAddressChanged", [setting]);
+            }
+        },
+        "gateway": {
+            "name": "Gateway",
+            "control": {
+                "type": "text",
+                "value": "192.168.0.254"
+            },
+            "event": "EthernetGatewayChanged",
+            "callback": function (setting) {
+                event.trigger("EthernetGatewayChanged", [setting]);
+            }
+        },
+        "dns": {
+            "name": "DNS",
+            "control": {
+                "type": "text",
+                "value": "192.168.30.50"
+            },
+            "event": "EthernetDnsChanged",
+            "callback": function (setting) {
+                event.trigger("EthernetDnsChanged", [setting]);
+            }
+        },
+        "subnetMask": {
+            "name": "Subnet Mask",
+            "control": {
+                "type": "text",
+                "value": "192.168.0.0"
+            },
+            "event": "EthernetSubnetMaskChanged",
+            "callback": function (setting) {
+                event.trigger("EthernetSubnetMaskChanged", [setting]);
+            }
+        }
+    },
+    "SIM": {
+        "operatorName": {
+            "name": "Operator Name",
+            "control": {
+                "type": "text",
+                "value": "Tizen"
+            },
+            "event": "SimOperatorNameChanged",
+            "callback": function (setting) {
+                event.trigger("SimOperatorNameChanged", [setting]);
+            }
+        },
+        "msisdn": {
+            "name": "MSISDN",
+            "control": {
+                "type": "text",
+                "value": "088123456789"
+            },
+            "event": "SimMsisdnChanged",
+            "callback": function (setting) {
+                event.trigger("SimMsisdnChanged", [setting]);
+            }
+        },
+        "iccid": {
+            "name": "ICCID",
+            "control": {
+                "type": "text",
+                "value": "123000MFSSYYGXXXXXXP"
+            },
+            "event": "SimIccidChanged",
+            "callback": function (setting) {
+                event.trigger("SimIccidChanged", [setting]);
+            }
+        },
+        "mcc": {
+            "name": "MCC",
+            "control": {
+                "type": "text",
+                "value": "460"
+            },
+            "event": "SimMccChanged",
+            "callback": function (setting) {
+                event.trigger("SimMccChanged", [setting]);
+            }
+        },
+        "mnc": {
+            "name": "MNC",
+            "control": {
+                "type": "text",
+                "value": "0"
+            },
+            "event": "SimMncChanged",
+            "callback": function (setting) {
+                event.trigger("SimMncChanged", [setting]);
+            }
+        },
+        "msin": {
+            "name": "MSIN",
+            "control": {
+                "type": "text",
+                "value": "H1 H2 H3 S 12345"
+            },
+            "event": "SimMsinChanged",
+            "callback": function (setting) {
+                event.trigger("SimMsinChanged", [setting]);
+            }
+        },
+        "spn": {
+            "name": "SPN",
+            "control": {
+                "type": "text",
+                "value": "TizenSPN"
+            },
+            "event": "SimSpnChanged",
+            "callback": function (setting) {
+                event.trigger("SimSpnChanged", [setting]);
+            }
+        }
+    }
+
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/spec/ui', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    plugins: [
+        "accelerometer",
+        "messaging",
+        "call",
+        "geoView",
+        "time",
+        "widgetConfig",
+        "deviceSettings",
+        "sensorSettings",
+        "battery",
+        "application",
+        /* "bluetooth", */
+        "nfc",
+        "power"
+    ]
+};
+
+});
+require.define('ripple/platform/tizen/1.0/spec/config', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var platform = require('ripple/platform'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    constants = require('ripple/constants');
+
+module.exports = {
+    fileName: "config.xml",
+    validateVersion: function (configValidationObject) {
+        var valid = true;
+        // no xmlns:JIL in wac 2.0 spec
+        valid = !!configValidationObject.widget.validationResult[0].attributes.xmlns.valid;
+
+        return valid;
+    },
+    extractInfo: function (configValidationObject) {
+        if (!configValidationObject) {
+            return null;
+        }
+
+        var widgetInfo = {},
+            configFeatures,
+            configPreferences,
+            preferenceName,
+            platform;
+
+        widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
+        widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
+        widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
+        widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
+
+        widgetInfo.features = {};
+
+        configFeatures = configValidationObject.widget.children.feature.validationResult;
+        utils.forEach(configFeatures, function (f) {
+            if (f.valid === true) {
+                var feature = {id: f.attributes.name.value,
+                         required: f.attributes.required.valid};
+                widgetInfo.features[feature.id] = feature;
+            }
+        });
+
+        widgetInfo.preferences = {};
+
+        configPreferences = configValidationObject.widget.children.preference.validationResult;
+
+        platform = require('ripple/platform');
+        utils.forEach(configPreferences, function (preference) {
+            preferenceName = preference.attributes.name.value;
+            if (preferenceName) {
+                widgetInfo.preferences[preferenceName] = {
+                    "key": preferenceName,
+                    "value": preference.attributes.value.value || "",
+                    "readonly": preference.attributes.readonly.value === "true"
+                };
+
+                db.save(preferenceName,
+                        widgetInfo.preferences[preferenceName].value,
+                        platform.getPersistencePrefix(widgetInfo.id));
+            }
+        });
+
+        return widgetInfo;
+    },
+    schema: {
+        rootElement: "widget",
+        widget: {
+            nodeName: "widget",
+            required: true,
+            occurrence: 1,
+            helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in the configuration document and may have the following child elments: name,description,icon,author,license,content,feature and preference.The \"widget\" element MAY have following attributes: id,version,height,width, defaultlocale, xml:lang and dir",
+            attributes: {
+                xmlns: {
+                    attributeName: "xmlns",
+                    required: true,
+                    type: "list",
+                    listValues: ["http://www.w3.org/ns/widgets"]
+                },
+                "xmlns:tizen": {
+                    attributeName: "xmlns:tizen",
+                    required: false,
+                    type: "list",
+                    listValues: ["http://tizen.org/ns/widgets"]
+                },
+                "xml:lang": {
+                    attributeName: "xml:lang",
+                    required: false,
+                    type: "iso-language"
+                },
+                dir: {
+                    attributeName: "dir",
+                    required: false,
+                    type: "list",
+                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                },
+                id: {
+                    attributeName: "id",
+                    required: false,
+                    type: "string"
+                },
+                version: {
+                    attributeName: "version",
+                    required: false,
+                    type: "string"
+                },
+                height: {
+                    attributeName: "height",
+                    required: false,
+                    type: "integer"
+                },
+                width: {
+                    attributeName: "width",
+                    required: false,
+                    type: "integer"
+                },
+                viewmodes: {
+                    attributeName: "viewmodes",
+                    required: false,
+                    type: "list",
+                    listValues: ["windowed", "floating", "fullscreen", "maximized", "minimized"]
+                },
+                defaultlocale: {
+                    attributeName: "defaultlocale",
+                    required: false,
+                    type: "iso-language"
+                },
+            },
+            children: {
+                name: {
+                    nodeName: "name",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                            unique: true
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        "short": {
+                            attributeName: "short",
+                            required: false,
+                            type: "string"
+                        }
+                    },
+                    children: {
+                        span: {
+                            nodeName: "span",
+                            required: false,
+                            type: "string",
+                            attributes: {
+                                "xml:lang": {
+                                    attributeName: "xml:lang",
+                                    required: false,
+                                    type: "iso-language",
+                                    unique: true
+                                },
+                                dir: {
+                                    attributeName: "dir",
+                                    required: false,
+                                    type: "list",
+                                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                                }
+                            }
+                        }
+                    }
+                },
+                description: {
+                    nodeName: "description",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                            unique: true
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        }
+                    },
+                    children: {
+                        span: {
+                            nodeName: "span",
+                            required: false,
+                            type: "string",
+                            attributes: {
+                                "xml:lang": {
+                                    attributeName: "xml:lang",
+                                    required: false,
+                                    type: "iso-language",
+                                    unique: true
+                                },
+                                dir: {
+                                    attributeName: "dir",
+                                    required: false,
+                                    type: "list",
+                                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                                }
+                            }
+                        }
+                    }
+                },
+                author: {
+                    nodeName: "author",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        href: {
+                            attributeName: "href",
+                            required: false,
+                            type: "regex",
+                            regex: constants.REGEX.URL
+                        },
+                        email: {
+                            attributeName: "email",
+                            required: false,
+                            type: "regex",
+                            regex: constants.REGEX.EMAIL
+                        }
+                    },
+                    children: {
+                        span: {
+                            nodeName: "span",
+                            required: false,
+                            type: "string",
+                            attributes: {
+                                "xml:lang": {
+                                    attributeName: "xml:lang",
+                                    required: false,
+                                    type: "iso-language",
+                                    unique: true
+                                },
+                                dir: {
+                                    attributeName: "dir",
+                                    required: false,
+                                    type: "list",
+                                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                                }
+                            }
+                        }
+                    }
+                },
+                license: {
+                    nodeName: "license",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        href: {
+                            attributeName: "href",
+                            type: "regex",
+                            required: false,
+                            regex: constants.REGEX.URL
+                        }
+                    },
+                    children: {
+                        span: {
+                            nodeName: "span",
+                            required: false,
+                            type: "string",
+                            attributes: {
+                                "xml:lang": {
+                                    attributeName: "xml:lang",
+                                    required: false,
+                                    type: "iso-language",
+                                    unique: true
+                                },
+                                dir: {
+                                    attributeName: "dir",
+                                    required: false,
+                                    type: "list",
+                                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                                }
+                            }
+                        }
+                    }
+                },
+                icon: {
+                    nodeName: "icon",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        src: {
+                            attributeName: "src",
+                            required: true,
+                            type: "string"
+                        },
+                        width: {
+                            attributeName: "width",
+                            required: false,
+                            type: "integer"
+                        },
+                        height: {
+                            attributeName: "height",
+                            required: false,
+                            type: "integer"
+                        }
+                    }
+                },
+                content: {
+                    nodeName: "content",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                            unique: true
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        src: {
+                            attributeName: "src",
+                            required: true,
+                            type: "string"
+                        },
+                        encoding: {
+                            attributeName: "encoding",
+                            required: false,
+                            type: "string"
+                        },
+                        type: {
+                            attributeName: "type",
+                            required: false,
+                            type: "string"
+                        }
+                    }
+                },
+                feature: {
+                    nodeName: "feature",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        name: {
+                            attributeName: "name",
+                            required: true,
+                            type: "list",
+                            listValues: ["http://www.w3.org/TR/geolocation-API/",
+                                         "http://www.w3.org/TR/battery-status/",
+                                         "http://www.w3.org/TR/vibration/",
+                                         "http://www.w3.org/TR/touch-events/",
+                                         "http://wacapps.net/api/deviceapis", "http://wacapps.net/api/accelerometer",
+                                         "http://wacapps.net/api/orientation", "http://wacapps.net/api/camera",
+                                         "http://wacapps.net/api/camera.show", "http://wacapps.net/api/camera.capture",
+                                         "http://wacapps.net/api/devicestatus", "http://wacapps.net/api/devicestatus.deviceinfo",
+                                         "http://wacapps.net/api/devicestatus.networkinfo", "http://wacapps.net/api/filesystem",
+                                         "http://wacapps.net/api/filesystem.read", "http://wacapps.net/api/filesystem.write",
+                                         "http://wacapps.net/api/messaging", "http://wacapps.net/api/messaging.send",
+                                         "http://wacapps.net/api/messaging.find", "http://wacapps.net/api/messaging.subscribe",
+                                         "http://wacapps.net/api/messaging.write", "http://wacapps.net/api/pim.contact",
+                                         "http://wacapps.net/api/pim.contact.read", "http://wacapps.net/api/pim.contact.write",
+                                         "http://wacapps.net/api/pim.calendar", "http://wacapps.net/api/pim.calendar.read",
+                                         "http://wacapps.net/api/pim.calendar.write", "http://wacapps.net/api/pim.task",
+                                         "http://wacapps.net/api/pim.task.read", "http://wacapps.net/api/pim.task.write",
+                                         "http://wacapps.net/api/deviceinteraction",
+                                         "http://tizen.org/api/tizen", "http://tizen.org/api/application",
+                                         "http://tizen.org/api/application.launch", "http://tizen.org/api/application.kill",
+                                         "http://tizen.org/api/application.read",
+                                         "http://tizen.org/api/time", "http://tizen.org/api/time.read",
+                                         "http://tizen.org/api/time.write", "http://tizen.org/api/alarm",
+                                         "http://tizen.org/api/alarm.read", "http://tizen.org/api/alarm.write",
+                                         "http://tizen.org/api/contact", "http://tizen.org/api/contact.read",
+                                         "http://tizen.org/api/contact.write", "http://tizen.org/api/filesystem",
+                                         "http://tizen.org/api/filesystem.write", "http://tizen.org/api/filesystem.read",
+                                         "http://tizen.org/api/calendar", "http://tizen.org/api/calendar.read",
+                                         "http://tizen.org/api/calendar.write", "http://tizen.org/api/call",
+                                         "http://tizen.org/api/call.state", "http://tizen.org/api/lbs",
+                                         "http://tizen.org/api/call.history", "http://tizen.org/api/call.history.read",
+                                         "http://tizen.org/api/call.history.write", "http://tizen.org/api/messaging",
+                                         "http://tizen.org/api/messaging.send", "http://tizen.org/api/messaging.read",
+                                         "http://tizen.org/api/messaging.write",
+                                         /*
+                                         "http://tizen.org/api/bluetooth", "http://tizen.org/api/bluetooth.admin",
+                                         "http://tizen.org/api/bluetooth.gap", "http://tizen.org/api/bluetooth.spp",
+                                         */
+                                         "http://tizen.org/api/nfc", "http://tizen.org/api/nfc.tag",
+                                         "http://tizen.org/api/nfc.p2p",
+                                         "http://tizen.org/api/geocoder",
+                                         "http://tizen.org/api/mediacontent", "http://tizen.org/api/systeminfo",
+                                         "http://tizen.org/api/sensors", "http://tizen.org/api/power"]
+                        },
+                        required: {
+                            attributeName: "required",
+                            type: "boolean",
+                            required: false
+                        }
+                    },
+                    children: {
+                        param: {
+                            nodeName: "param",
+                            required: false,
+                            occurrence: 0,
+                            attributes: {
+                                "xml:lang": {
+                                    attributeName: "xml:lang",
+                                    required: false,
+                                    type: "iso-language",
+                                },
+                                dir: {
+                                    attributeName: "dir",
+                                    required: false,
+                                    type: "list",
+                                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                                },
+                                name: {
+                                    attributeName: "name",
+                                    required: true,
+                                    type: "string",
+                                },
+                                value: {
+                                    attributeName: "value",
+                                    required: true,
+                                    type: "string",
+                                }
+                            }
+                        }
+                    }
+                },
+                preference: {
+                    nodeName: "preference",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        name: {
+                            attributeName: "name",
+                            required: true,
+                            type: "string"
+                        },
+                        value: {
+                            type: "string",
+                            required: false,
+                            attributeName: "value"
+                        },
+                        readonly: {
+                            attributeName: "readonly",
+                            type: "boolean",
+                            required: false
+                        }
+                    }
+                }
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/platform/tizen/1.0/ApplicationService', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var event = require('ripple/event'),
+    tizen1_utils = require('ripple/platform/tizen/1.0/tizen1_utils'),
+    ApplicationServiceData = require('ripple/platform/tizen/1.0/ApplicationServiceData');
+
+module.exports = function (operation, uri, mime, data) {
+    var _self, i;
+
+    _self = {
+        operation: "",
+        url: "",
+        mime: "",
+        data: [],
+        replyResult: function (data) {
+            event.trigger("appServiceReplied", "Result: " + data);
+        },
+        replyFailure: function () {
+            event.trigger("appServiceReplied", "Failure");
+        }
+    };
+
+    _self.operation = String(operation);
+    if (uri) {
+        _self.uri = String(uri);
+    }
+    if (mime) {
+        _self.mime = String(mime);
+    }
+    if (tizen1_utils.isValidArray(data)) {
+        for (i in data) {
+            _self.data.push(new ApplicationServiceData(data[i].key, data[i].value));
+        }
+    }
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/ContactOrganization', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+module.exports = function (prop) {
+    var _self;
+    _self = {
+        name : null,
+        department : null,
+        office : null,
+        title : null,
+        role : null,
+        logoURI : null,
+    };
+
+    if (prop) {
+        if (prop.name !== null && prop.name !== undefined) {
+            _self.name = String(prop.name);
+        }
+        if (prop.department !== null && prop.department !== undefined) {
+            _self.department = String(prop.department);
+        }
+        if (prop.office !== null && prop.office !== undefined) {
+            _self.office = String(prop.office);
+        }
+        if (prop.title !== null && prop.title !== undefined) {
+            _self.title = String(prop.title);
+        }
+        if (prop.role !== null && prop.role !== undefined) {
+            _self.role = String(prop.role);
+        }
+        if (prop.logoURI !== null && prop.logoURI !== undefined) {
+            _self.logoURI = String(prop.logoURI);
+        }
+    }
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/spec', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = {
+
+    id: "tizen",
+    version: "1.0",
+    name: "TIZEN",
+
+    persistencePrefix: "tizen1-",
+
+    config: require('ripple/platform/tizen/1.0/spec/config'),
+    ui: require('ripple/platform/tizen/1.0/spec/ui'),
+    device: require('ripple/platform/tizen/1.0/spec/device'),
+    sensor: require('ripple/platform/tizen/1.0/spec/sensor'),
+    DeviceMotionEvent: require('ripple/platform/tizen/1.0/DeviceMotionEvent'),
+    DeviceOrientationEvent: require('ripple/platform/tizen/1.0/DeviceOrientationEvent'),
+
+    objects: {
+        Coordinates: {
+            path: "w3c/1.0/Coordinates"
+        },
+        Position: {
+            path: "w3c/1.0/Position"
+        },
+        PositionError: {
+            path: "w3c/1.0/PositionError"
+        },
+        SensorConnection: {
+            path: "w3c/1.0/SensorConnection"
+        },
+        Notification: {
+            path: "tizen/1.0/Notification"
+        },
+        navigator: {
+            path: "tizen/1.0/navigator",
+            children: {
+                geolocation: {
+                    path: "wac/2.0/geolocation",
+                    feature: "http://www.w3.org/TR/geolocation-API/"
+                },
+                battery: {
+                    path: "tizen/1.0/battery",
+                    feature: "http://www.w3.org/TR/battery-status/"
+                }
+            }
+        },
+        tizen: {
+            feature: "http://tizen.org/api/tizen",
+            children: {
+                CompositeFilter: {
+                    path: "tizen/1.0/CompositeFilter"
+                },
+                AttributeFilter: {
+                    path: "tizen/1.0/AttributeFilter"
+                },
+                AttributeRangeFilter: {
+                    path: "tizen/1.0/AttributeRangeFilter"
+                },
+                SortMode: {
+                    path: "tizen/1.0/SortMode"
+                },
+                alarm: {
+                    path: "tizen/1.0/alarm",
+                    feature: "http://tizen.org/api/alarm|http://tizen.org/api/alarm.read|http://tizen.org/api/alarm.write",
+                    handleSubfeatures: true
+                },
+                AlarmRelative: {
+                    path: "tizen/1.0/AlarmRelative"
+                },
+                AlarmAbsolute: {
+                    path: "tizen/1.0/AlarmAbsolute"
+                },
+                application: {
+                    path: "tizen/1.0/application",
+                    feature: "http://tizen.org/api/application|http://tizen.org/api/application.launch|http://tizen.org/api/application.kill|http://tizen.org/api/application.read",
+                    handleSubfeatures: true
+                },
+                ApplicationService: {
+                    path: "tizen/1.0/ApplicationService"
+                },
+                ApplicationServiceData: {
+                    path: "tizen/1.0/ApplicationServiceData"
+                },
+                /*
+                bluetooth: {
+                    path: "tizen/1.0/bluetooth",
+                    feature: "http://tizen.org/api/bluetooth|http://tizen.org/api/bluetooth.admin|http://tizen.org/api/bluetooth.gap|http://tizen.org/api/bluetooth.spp",
+                    handleSubfeatures: true
+                },
+                */
+                ContactName: {
+                    path: "tizen/1.0/ContactName"
+                },
+                ContactOrganization: {
+                    path: "tizen/1.0/ContactOrganization"
+                },
+                ContactWebSite: {
+                    path: "tizen/1.0/ContactWebSite"
+                },
+                ContactAnniversary: {
+                    path: "tizen/1.0/ContactAnniversary"
+                },
+                ContactAccount: {
+                    path: "tizen/1.0/ContactAccount"
+                },
+                ContactAddress: {
+                    path: "tizen/1.0/ContactAddress"
+                },
+                ContactPhoneNumber: {
+                    path: "tizen/1.0/ContactPhoneNumber"
+                },
+                ContactEmailAddress: {
+                    path: "tizen/1.0/ContactEmailAddress"
+                },
+                ContactRef: {
+                    path: "tizen/1.0/ContactRef"
+                },
+                Contact: {
+                    path: "tizen/1.0/ContactBase"
+                },
+                call: {
+                    path: "tizen/1.0/call",
+                    feature: "http://tizen.org/api/call|http://tizen.org/api/call.history|http://tizen.org/api/call.history.read|http://tizen.org/api/call.history.write",
+                    handleSubfeatures: true
+                },
+                SimpleCoordinates: {
+                    path: "tizen/1.0/SimpleCoordinates"
+                },
+                TZDate: {
+                    path: "tizen/1.0/TZDate"
+                },
+                TimeDuration: {
+                    path: "tizen/1.0/TimeDuration"
+                },
+                Message: {
+                    path: "tizen/1.0/Message"
+                },
+                time: {
+                    path: "tizen/1.0/time",
+                    feature: "http://tizen.org/api/time|http://tizen.org/api/time.read|http://tizen.org/api/time.write",
+                    handleSubfeatures: true
+                },
+                contact: {
+                    path: "tizen/1.0/contact",
+                    feature: "http://tizen.org/api/contact|http://tizen.org/api/contact.read|http://tizen.org/api/contact.write",
+                    handleSubfeatures: true
+                },
+                calendar: {
+                    path: "tizen/1.0/calendar",
+                    feature: "http://tizen.org/api/calendar|http://tizen.org/api/calendar.read|http://tizen.org/api/calendar.write",
+                    handleSubfeatures: true
+                },
+                CalendarItem: {
+                    path: "tizen/1.0/CalendarItem"
+                },
+                CalendarEvent: {
+                    path: "tizen/1.0/CalendarEvent"
+                },
+                CalendarTask: {
+                    path: "tizen/1.0/CalendarTask"
+                },
+                CalendarRecurrenceRule: {
+                    path: "tizen/1.0/CalendarRecurrenceRule"
+                },
+                messaging: {
+                    path: "tizen/1.0/messaging",
+                    feature: "http://tizen.org/api/messaging|http://tizen.org/api/messaging.send|http://tizen.org/api/messaging.read|http://tizen.org/api/messaging.write",
+                    handleSubfeatures: true
+                },
+                nfc: {
+                    path: "tizen/1.0/nfc",
+                    feature: "http://tizen.org/api/nfc|http://tizen.org/api/nfc.tag|http://tizen.org/api/nfc.p2p",
+                    handleSubfeatures: true
+                },
+                lbs: {
+                    children: {
+                        geocoder: {
+                            path: "tizen/1.0/geocoder",
+                            feature: "http://tizen.org/api/geocoder"
+                        },
+                        GeoRectBounds: {
+                            path: "tizen/1.0/GeoRectBounds"
+                        },
+                        GeoCircleBounds: {
+                            path: "tizen/1.0/GeoCircleBounds"
+                        },
+                        GeoPolyBounds: {
+                            path: "tizen/1.0/GeoPolyBounds"
+                        },
+                        GeometryFilter: {
+                            path: "tizen/1.0/GeometryFilter"
+                        }
+                    }
+                },
+                mediacontent: {
+                    path: "tizen/1.0/mediacontent",
+                    feature: "http://tizen.org/api/mediacontent"
+                },
+                sensors: {
+                    path: "tizen/1.0/sensors",
+                    feature: "http://tizen.org/api/sensors"
+                },
+                systeminfo: {
+                    path: "tizen/1.0/systeminfo",
+                    feature: "http://tizen.org/api/systeminfo"
+                },
+                filesystem: {
+                    path: "tizen/1.0/filesystem",
+                    feature: "http://tizen.org/api/filesystem|http://tizen.org/api/filesystem.read|http://tizen.org/api/filesystem.write"
+                },
+                power: {
+                    path: "tizen/1.0/power",
+                    feature: "http://tizen.org/api/power"
+                },
+                PowerStateRequest: {
+                    path: "tizen/1.0/PowerStateRequest",
+                    feature: "http://tizen.org/api/power"
+                }
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/platform/tizen/1.0/ContactWebSite', function (require, module, exports) {
+/*      
+ *  Copyright 2012 Intel Corporation.
+ *  
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+module.exports = function (url, type) {
+    var _self, _url, _type;
+
+    if (url) {
+        _url = String(url);
+    }
+
+    if (type) {
+        _type = String(type).toUpperCase();
+    }
+
+    _self = {
+        url : _url,
+        type: _type
+    };
+
+    return _self;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/GeoPolyBounds', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (_points) {
+    var points = _points || [];
+
+    this.__defineGetter__("points", function () {
+        return points;
+    });
+};
+
+});
+require.define('ripple/platform/tizen/1.0/MessageFolder', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (opt) {
+    var folder = {}, _id = opt.id, _parentId = null, _serviceId = opt.serviceId,
+        _contentType = opt.contentType, _name = opt.id, _path = opt.path,
+        _type = opt.type, _synchronizable = opt.synchronizable;
+
+    folder.name = _name;
+    folder.synchronizable = _synchronizable;
+    
+    folder.__defineGetter__("id", function () {
+        return _id;
+    });
+    folder.__defineGetter__("parentId", function () {
+        return _parentId;
+    });
+    folder.__defineGetter__("serviceId", function () {
+        return _serviceId;
+    });
+    folder.__defineGetter__("contentType", function () {
+        return _contentType;
+    });
+    folder.__defineGetter__("path", function () {
+        return _path;
+    });
+    folder.__defineGetter__("type", function () {
+        return _type;
+    });
+    return folder;
+};
+
+});
+require.define('ripple/platform/tizen/1.0/pendingoperation', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (pendingObj) {
+    var pending = true;
+    this.cancel = function () {
+        if (pending === true) {
+            if (typeof (pendingObj.getCancelFlag) === "function" && pendingObj.getCancelFlag() === false) {
+                pending = false;
+                // this clearTimeout is for the case when a 3rd party is invoked to do the task, and it's finished sooner than the intended timeout. therefore, the 3rd party set CancelFlag false, and this cancel is called before timeout
+                clearTimeout(pendingObj.pendingID);
+                return false;
+            }
+            if (typeof (pendingObj.userCancel) === "function") {
+                pendingObj.userCancel();
+            }
+            clearTimeout(pendingObj.pendingID);
+            pending = false;
+            return true;
+        } else {
+            return false;
+        }
+    };
+};
+
+
+});
+require.define('ripple/platform/tizen/1.0/WebAPIError', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var errorcode = require('ripple/platform/tizen/1.0/errorcode');
+
+var msg = {
+    0: "Generic Error",
+    1: "Index or size is negative, or greater than the allowed value.",
+    2: "Specified range of text does not fit into a DOMString.",
+    3: "Node is inserted somewhere it doesn't belong.",
+    4: "Node is used in a different document than the one that created it (that doesn't support it).",
+    5: "An invalid or illegal character is specified.",
+    6: "Data is specified for a Node which does not support data.",
+    7: "An attempt is made to modify an object where modifications are not allowed.",
+    8: "An attempt is made to reference a Node in a context where it does not exist.",
+    9: "The implementation does not support the requested type of object or operation.",
+    10: "An attempt is made to add an attribute that is already in use elsewhere.",
+    11: "An attempt is made to use an object that is not, or is no longer, usable.",
+    12: "An invalid or illegal string is specified.",
+    13: "An attempt is made to modify the type of the underlying object.",
+    14: "An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.",
+    15: "A parameter or an operation is not supported by the underlying object.",
+    16: "A call to a method such as insertBefore or removeChild would make the Node invalid with respect to \"partial validity\", this exception would be raised and the operation would not be done.",
+    17: "The type of an object is incompatible with the expected type of the parameter associated to the object.",
+    18: "An attempt is made to perform an operation or access some data in a way that would be a security risk or a violation of the user agent's security policy.",
+    19: "A network error occurs in synchronous requests.",
+    20: "The abort error occurs in asynchronous requests by user prompt.",
+    21: "The operation could not be completed because the URL does not match.",
+    22: "The quota has been exceeded.",
+    23: "The operation timed out.",
+    24: "The supplied node is incorrect or has an incorrect ancestor for this operation.",
+    25: "The object can not be cloned.",
+    99: "The content of an object does not include valid values.",
+    100: "Error occurred in communication with the underlying implementation that meant the requested method could not complete.",
+    111: "Requested service is not available."
+};
+/*
+  support 3 types of error:
+  - WebAPIError()
+      code = errorcode.UNKNOWN_ERR
+      message = errorcode.message[UNKNOWN_ERR]
+  - WebAPIError(errorcode."TYPE_MISMATCH_ERR")
+      code = 17
+      message = errorcode.message[17]
+  - WebAPIError(my_own_error_code, "This is my error message.")
+      code = my_own_error_code(number)
+      message = "This is my error message."
+*/
+
+module.exports = function (code, message) {
+    var g, c, _code, _message;
+
+    for (c in errorcode) {
+        g = errorcode.__lookupGetter__(c);
+        if (g) {
+            this.__defineGetter__(c, g);
+        }
+    }
+
+    if (typeof code !== 'number') {
+        _code = errorcode.UNKNOWN_ERR;
+        _message = errorcode.message[_code];
+    } else {
+        _code = code;
+        if (typeof message === 'string') {
+            _message = message;
+        } else {
+            _message = msg[_code];
+        }
+    }
+
+    this.__defineGetter__("code", function () {
+        return _code;
+    });
+    this.__defineGetter__("message", function () {
+        return _message;
+    });
+};
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/fsCache', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var fs = require('ripple/dbfs'),
+    utils = require('ripple/utils'),
+    _console = require('ripple/console'),
+    constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    bbUtils = require('ripple/platform/webworks.core/2.0.0/client/utils'),
+    FileProperties = require('ripple/platform/webworks.core/2.0.0/client/FileProperties'),
+    _cache = {},
+    _self;
+
+function _createPath(path) {
+    var parts = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
+        workflow = jWorkflow.order();
+
+    parts.forEach(function (part, index) {
+        var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/");
+
+        workflow.andThen(function (prev, baton) {
+            baton.take();
+            fs.mkdir(dir, baton.pass, baton.pass);
+        });
+    });
+
+    workflow.start(_self.refresh);
+}
+event.on("FileSystemInitialized", function () {
+    _createPath("/SDCard");
+    _createPath("/store/home/user/music");
+    _createPath("/store/home/user/pictures");
+    _createPath("/store/home/user/videos");
+    _createPath("/store/home/user/videos");
+    _createPath("/accounts/1000/appdata/emulatedapp/data");
+    _createPath("/accounts/1000/appdata/emulatedapp/shared/bookmarks");
+    _createPath("/accounts/1000/appdata/emulatedapp/shared/books");
+    _createPath("/accounts/1000/appdata/emulatedapp/shared/camera");
+    _createPath("/accounts/1000/appdata/emulatedapp/shared/documents");
+    _createPath("/accounts/1000/appdata/emulatedapp/shared/downloads");
+    _createPath("/accounts/1000/appdata/emulatedapp/shared/misc");
+    _createPath("/accounts/1000/appdata/emulatedapp/shared/music");
+    _createPath("/accounts/1000/appdata/emulatedapp/shared/photos");
+    _createPath("/accounts/1000/appdata/emulatedapp/shared/print");
+    _createPath("/accounts/1000/appdata/emulatedapp/shared/videos");
+    _createPath("/accounts/1000/appdata/emulatedapp/shared/voice");
+});
+
+function _fsError(e) {
+    _self.refresh();
+    if (e.code !== 1) { // suppress file not found error
+        _console.error("FileSystem error (code " + e.code + ")");
+    }
+}
+
+function _walk(path, parent) {
+    fs.ls(path, function (entries) {
+        parent.children = parent.children || {};
+
+        entries.forEach(function (entry) {
+            parent.children[entry.name] = entry;
+            parent.children[entry.name].properties = {};
+
+            if (entry.isDirectory) {
+                _walk(entry.fullPath, entry);
+            } else {
+                entry.file(function (file) {
+                    utils.mixin(file, parent.children[entry.name].properties);
+                });
+                fs.read(entry.fullPath, function (data) {
+                    parent.children[entry.name].data = data;
+                }, function (e) {
+                    console.error(e);
+                });
+            }
+        });
+    }, function (e) {
+        console.error(e);
+    });
+}
+
+function _get(path) {
+    return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
+        return token === "" ? obj : (obj && obj.children ? obj.children[token] || null : null);
+    }, _cache);
+}
+
+function _getInfo(path) {
+    var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
+        name = parent.splice(parent.length - 1, 1).join(""),
+        ext = name.split(".");
+
+    return {
+        name: name,
+        extension: ext.length > 1 ? ext[ext.length - 1] : "",
+        hidden: (name.length > 0 && name[0] === ".") || false,
+        parent: parent.join("/") || "/"
+    };
+}
+
+function _set(path, obj) {
+    var parent = _cache,
+        tokens = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
+        child = tokens.splice(tokens.length - 1, 1).join("");
+
+    tokens.forEach(function (token) {
+        parent = parent.children[token];
+    });
+
+    parent.children = parent.children || {};
+    obj.properties = obj.properties || {};
+    parent.children[child] = obj;
+}
+
+function _delete(path) {
+    var parent = _cache,
+        tokens = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
+        child = tokens.splice(tokens.length - 1, 1).join("");
+
+    tokens.forEach(function (token) {
+        parent = parent.children[token];
+    });
+
+    delete parent.children[child];
+}
+
+// TODO: handle exceptions so that any respective fs command can error out
+// TODO: dateCreated is always dateModified
+
+_self = {
+    refresh: function () {
+        _cache = {};
+        _walk("/", _cache);
+    },
+    file: {
+        exists: function (path) {
+            var entry = _get(path);
+            return !!(entry && !entry.isDirectory);
+        },
+
+        deleteFile: function (path) {
+            _delete(path);
+            fs.rm(path, function () {}, _fsError);
+        },
+
+        copy: function (from, to) {
+            var fromEntry = _get(from);
+
+            _set(to, {
+                fullPath: to,
+                properties: fromEntry.properties,
+                data: fromEntry.data
+            });
+
+            fs.cp(from, to, function (entry) {
+                entry.file(function (file) {
+                    entry.properties = entry.properties || {};
+                    utils.mixin(file, entry.properties);
+                    _set(to, entry);
+                });
+            }, _fsError);
+        },
+
+        getFileProperties: function (path) {
+            var entry = _get(path),
+                info = _getInfo(path);
+
+            fs.stat(path, function () {}, _fsError);
+
+            return new FileProperties({
+                dateCreated: entry.lastModifiedDate,
+                dateModified: entry.lastModifiedDate,
+                directory: info.parent,
+                fileExtension: info.extension,
+                isHidden: info.hidden,
+                isReadonly: false,
+                mimeType: entry.properties.type,
+                size: entry.properties.size
+            });
+        },
+
+        rename: function (path, newName) {
+            _self.dir.rename(path, newName);
+        },
+
+        readFile: function (path, success, async) {
+            var entry = _get(path);
+
+            async = async === false ? async : true;
+
+            if (!async) {
+                success(bbUtils.stringToBlob(entry.data));
+            }
+            else {
+                fs.read(path, function (data) {
+                    var blob = bbUtils.stringToBlob(data);
+                    if (async) {
+                        success(blob);
+                    }
+                    entry.data = data;
+                    _set(path, entry);
+                }, _fsError);
+            }
+        },
+
+        saveFile: function (path, blob) {
+            var data = bbUtils.blobToString(blob);
+
+            _set(path, {
+                lastModifiedDate: new Date(),
+                fullPath: path,
+                isDirectory: false,
+                properties: {
+                    type: "",
+                    size: blob.size
+                },
+                data: data
+            });
+
+            fs.write(path, data, function (entry) {
+                entry.data = data;
+                entry.file(function (file) {
+                    entry.properties = entry.properties || {};
+                    utils.mixin(file, entry.properties);
+                    _set(path, entry);
+                });
+            }, _fsError);
+        }
+    },
+    dir: {
+        createNewDir: function (path) {
+            var entry = _get(path),
+                info = _getInfo(path);
+
+            if (!entry) {
+                _set(path, {
+                    name: info.name,
+                    isDirectory: true,
+                    fullPath: path
+                });
+            }
+
+            fs.mkdir(path, function (entry) {
+                _set(path, entry);
+            }, _fsError);
+        },
+
+        deleteDirectory: function (path, recursive) {
+            _delete(path);
+            if (recursive) {
+                fs.rm(path, function () {}, _fsError, {recursive: recursive});
+            } else {
+                fs.rmdir(path, function () {}, _fsError);
+            }
+        },
+
+        exists: function (path) {
+            var entry = _get(path);
+            return !!(entry && entry.isDirectory);
+        },
+
+        getFreeSpaceForRoot: function (path) {
+            function _du(obj, size) {
+                utils.forEach(obj, function (child, key) {
+                    if (child.isDirectory && child.children) {
+                        size += _du(child.children, size);
+                    } else if (child.properties && child.properties.size) {
+                        size += child.properties.size;
+                    }
+                });
+                return size;
+            }
+
+            return constants.FS_SIZE - _du(_cache.children, 0);
+        },
+
+        getParentDirectory: function (path) {
+            path = "/" + path.replace(/^\//, '').replace(/\/$/, '');
+
+            var entry = _get(path),
+                array = path.split("/");
+
+            return entry ? array.splice(0, array.length - 1).join("/") || "/" : null;
+        },
+
+        listDirectories: function (path) {
+            var dir = _get(path),
+                directories = [];
+
+            utils.forEach(dir.children, function (item) {
+                if (item.isDirectory) {
+                    directories.push(item.name);
+                }
+            });
+
+            fs.ls(path, function () {}, _fsError);
+
+            return directories;
+        },
+
+        listFiles: function (path) {
+            var dir = _get(path),
+                files = [];
+
+            if (dir) {
+                utils.forEach(dir.children, function (item) {
+                    if (!item.isDirectory) {
+                        files.push(item.name);
+                    }
+                });
+            }
+
+            fs.ls(path, function () {}, _fsError);
+
+            return files;
+        },
+
+        rename: function (path, newName) {
+            var info = _getInfo(path),
+                parent = info.parent,
+                oldName = info.name,
+                from = (parent === "/" ? "" : parent) + "/" + oldName,
+                to =  (parent === "/" ? "" : parent) + "/" + newName;
+
+            _delete(from);
+            _set(to, {
+                name: info.name,
+                fullPath: path
+            });
+
+            fs.mv(from, to, function (entry) {
+                _set(to, entry);
+            }, _fsError);
+        },
+
+        getRootDirs: function () {
+            return _self.dir.listDirectories("/");
+        }
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/server/io/dir', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var cache = require('ripple/platform/webworks.core/2.0.0/fsCache');
+
+function _packet(data) {
+    return {
+        code: 1,
+        data: data
+    };
+}
+
+module.exports = {
+    createNewDir: function (get, post, baton) {
+        cache.dir.createNewDir(post.path);
+        return _packet();
+    },
+    deleteDirectory: function (get, post, baton) {
+        cache.dir.deleteDirectory(post.path, post.recursive);
+        return _packet();
+    },
+    exists: function (get, post, baton) {
+        return _packet(cache.dir.exists(post.path));
+    },
+    getParentDirectory: function (get, post, baton) {
+        return _packet(cache.dir.getParentDirectory(post.path));
+    },
+    listDirectories: function (get, post, baton) {
+        return _packet(cache.dir.listDirectories(post.path));
+    },
+    listFiles: function (get, post, baton) {
+        return _packet(cache.dir.listFiles(post.path));
+    },
+    rename: function (get, post, baton) {
+        cache.dir.rename(post.path, post.newName);
+        return _packet();
+    }
+};
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/server/io/file', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var cache = require('ripple/platform/webworks.core/2.0.0/fsCache'),
+    constants = require('ripple/constants'),
+    notifications = require('ripple/notifications');
+
+function _packet(data) {
+    return {
+        code: 1,
+        data: data
+    };
+}
+
+module.exports = {
+    copy: function (get, post, baton) {
+        cache.file.copy(post.from, post.to);
+        return _packet();
+    },
+    deleteFile: function (get, post, baton) {
+        cache.file.deleteFile(post.path);
+        return _packet();
+    },
+    exists: function (get, post, baton) {
+        return _packet(cache.file.exists(post.path));
+    },
+    getFileProperties: function (get, post, baton) {
+        return _packet(cache.file.getFileProperties(post.path));
+    },
+    open: function (get, post, baton) {
+        var msg = "Attempting to open file: " + post.path;
+        notifications.openNotification("normal", msg);
+        return _packet(cache.file.exists(post.path));
+    },
+    readFile: function (get, post, baton) {
+        var val;
+
+        if (post.async) {
+            baton.take();
+        }
+
+        cache.file.readFile(post.path, function (data) {
+            if (post.async) {
+                baton.pass(_packet({
+                    fullPath: post.path,
+                    blobData: data
+                }));
+            } else {
+                val = data;
+            }
+        }, post.async);
+
+        if (!post.async) {
+            return _packet({
+                fullPath: post.path,
+                blobData: val
+            });
+        }
+    },
+    rename: function (get, post, baton) {
+        cache.file.rename(post.path, post.newName);
+        return _packet();
+    },
+    saveFile: function (get, post, baton) {
+        cache.file.saveFile(post.path, post.blob);
+        return _packet();
+    }
+};
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/server/system', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var deviceSettings = require('ripple/deviceSettings'),
+    devices = require('ripple/devices'),
+    app = require('ripple/app'),
+    client = require('ripple/platform/webworks.core/2.0.0/client/system'),
+    utils = require('ripple/utils'),
+    notifications = require('ripple/notifications'),
+    constants = require('ripple/constants'),
+    platform = require('ripple/platform'),
+    _self;
+
+function _is(feature) {
+    return {
+        allowedFor: function (location) {
+            return feature && feature.URIs.some(function (uri) {
+                return uri.value === location ||
+                      (location.indexOf(uri.value) >= 0 && uri.subdomains);
+            });
+        }
+    };
+}
+
+_self = {
+    hasCapability: function (args) {
+        var capabilities = devices.getCurrentDevice().capabilities;
+        return {
+            code: 1,
+            data: capabilities ? capabilities.some(function (type) {
+                return type === args.capability;
+            }) : false
+        };
+    },
+    isMassStorageActive: function () {
+        return {code: 1, data: deviceSettings.retrieveAsBoolean("system.isMassStorageActive")};
+    },
+    hasDataCoverage: function () {
+        return {code: 1, data: deviceSettings.retrieveAsBoolean("system.hasDataCoverage")};
+    },
+    softwareVersion: function () {
+        return {code: 1, data: devices.getCurrentDevice().osVersion};
+    },
+    model: function () {
+        return {code: 1, data: devices.getCurrentDevice().model};
+    },
+    scriptApiVersion: function () {
+        return {code: 1, data: platform.current().version};
+    },
+    setHomeScreenBackground: function (args) {
+        var path = args.filePath,
+            msg = "Set home screen background to " + path + ".";
+        notifications.openNotification("normal", msg);
+        return {code: 1};
+    },
+    hasPermission: function (args) {
+        var info = app.getInfo(),
+            feature = info.features ? info.features[args.desiredModule] : null;
+
+        return {code: 1, data: feature === null || _is(feature).allowedFor(utils.location().href) ? client.ALLOW : client.DENY};
+    },
+    network: function () {
+        return {code: 1, data: deviceSettings.retrieve("system.network")};
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/select', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    _select,
+    _predicates = {
+        "==": function (left, right) {
+            return left === right;
+        },
+        "!=": function (left, right) {
+            return left !== right;
+        },
+        "<": function (left, right) {
+            return left < right;
+        },
+        ">": function (left, right) {
+            return left > right;
+        },
+        "<=": function (left, right) {
+            return left <= right;
+        },
+        ">=": function (left, right) {
+            return left >= right;
+        },
+        "REGEX": function (left, right) {
+            return left.match(new RegExp(right));
+        },
+        "CONTAINS": function (left, right) {
+            return left.indexOf(right) >= 0;
+        }
+    };
+
+function isFilter(field) {
+    return field && field.operator !== undefined && field.operator !== null;
+}
+
+function extractValue(item, field) {
+    return field.split(".").reduce(function (value, prop) {
+        return value[prop];
+    }, item);
+}
+
+function copy(items) {
+    //use a reduce to ensure that we always just return an array
+    //not the most performant but will whitewash the result
+    return utils.reduce(items, function (array, item) {
+        array.push(item);
+        return array;
+    }, []);
+}
+
+_select = {
+    ops: {
+        find: {
+            0: "!=",
+            1: "==",
+            2: "<",
+            3: "<=",
+            4: ">",
+            5: ">=",
+            8: "REGEX",
+            16: "AND",
+            32: "OR",
+            64: "CONTAINS"
+        },
+        phone: {
+            0: "!=",
+            1: "==",
+            2: "<",
+            3: "<=",
+            4: ">",
+            5: ">=",
+            8: "AND",
+            16: "OR",
+            32: "CONTAINS"
+        }
+    },
+    from: function (items) {
+        var _getPredicate = function (filter, operators) {
+
+                var noOp = function () {
+                        return false;
+                    },
+                    operator = (function () {
+                        var result = operators[filter.operator] || filter.operator,
+                            exists = function (op) {
+                                return result === op;
+                            };
+
+                        return utils.some(operators, exists) ? result : "";
+                    }());
+
+                return function (item) {
+                    var left = extractValue(item, filter.leftField),
+                        right = filter.rightField,
+                        predicate = _predicates[operator] || noOp;
+
+                    return filter.negate ? !predicate(left, right) : predicate(left, right);
+                };
+
+            },
+            _applyFilter = function (filter, operators) {
+                var result = [],
+                    left,
+                    right,
+                    op;
+
+                if (isFilter(filter.leftField) && isFilter(filter.rightField)) {
+
+                    left = _select.from(items).where(filter.leftField);
+                    right = _select.from(items).where(filter.rightField);
+                    op = operators[filter.operator] || filter.operator;
+
+                    switch (op) {
+                    case "AND":
+                        result = left.filter(function (item) {
+                            return right.indexOf(item) >= 0;
+                        });
+                        break;
+                    case "OR":
+                        result = left.concat(right.filter(function (item) {
+                            return left.indexOf(item) < 0;
+                        }));
+                        break;
+                    }
+
+                    if (filter.negate) {
+                        //reverse the result set.
+                        result = utils.filter(items, function (item) {
+                            return result.indexOf(item) < 0;
+                        });
+                    }
+                }
+                else {
+                    result = utils.filter(items, _getPredicate(filter, operators));
+                }
+
+                return result;
+            },
+            _orderBy,
+            _max,
+            _direction,
+            _self = {
+                orderBy: function (prop, dir) {
+                    _orderBy = prop;
+                    _direction = dir || "asc";
+                    return _self;
+                },
+                max: function (max) {
+                    _max = max;
+                    return _self;
+                },
+                where: function (filter, ops) {
+                    var result = isFilter(filter) ? _applyFilter(filter, ops || _select.ops.find) : copy(items);
+
+                    result.sort(function (a, b) {
+                        if (a[_orderBy] < b[_orderBy]) {
+                            return _direction === "asc" ? -1 : 1;
+                        }
+                        else if (a[_orderBy] > b[_orderBy]) {
+                            return _direction === "asc" ? 1: -1;
+                        }
+                        return 0;
+                    });
+
+                    return result.slice(0, _max === null || _max === -1 ? undefined : _max); // slice in V8 returns empty array if null
+                }
+            };
+
+        return _self;
+    }
+};
+
+module.exports = _select;
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/XMLHttpRequest', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    create: function (server) {
+        var XHR = window.XMLHttpRequest,
+            webworks = require(server);
+
+        return function () {
+            var _url,
+                _async,
+                xhr = new XHR(),
+                origMethods = {
+                    open: xhr.open,
+                    send: xhr.send,
+                    setRequestHeader: xhr.setRequestHeader
+                };
+
+            function onreadystatechange() {
+                if (typeof xhr.onreadystatechange === "function") {
+                    xhr.onreadystatechange();
+                }
+            }
+
+            function statemachine(getResult) {
+                var state = 0,
+                    incState = function (prev, baton) {
+                        state++;
+                        if (_async) {
+                            baton.take();
+                            window.setTimeout(baton.pass, 1);
+                        }
+                    },
+                    setResponse = function (result) {
+                        xhr.__defineGetter__("status", function () {
+                            return 200;
+                        });
+
+                        xhr.__defineGetter__("responseText", function () {
+                            return result !== null && result !== undefined ?
+                                JSON.stringify(result) : null;
+                        });
+                    };
+
+                xhr.__defineGetter__("readyState", function () {
+                    return state;
+                });
+
+                jWorkflow.order(incState)
+                         .andThen(onreadystatechange)
+                         .andThen(incState)
+                         .andThen(onreadystatechange)
+                         .andThen(incState)
+                         .andThen(onreadystatechange)
+                         .andThen(getResult)
+                         .andThen(setResponse)
+                         .andThen(incState)
+                         .andThen(onreadystatechange)
+                         .start();
+            }
+
+            xhr.setRequestHeader = function (header, value) {
+                if (!_url.match(/^webworks:\/\//)) {
+                    origMethods.setRequestHeader.apply(xhr, Array.prototype.slice.call(arguments));
+                }
+            };
+
+            xhr.open = function (method, url, async, user, password) {
+                _url = url;
+                _async = async;
+
+                if (!_url.match(/^webworks:\/\//)) {
+                    origMethods.open.apply(xhr, Array.prototype.slice.call(arguments));
+                }
+            };
+
+            xhr.send = function (post) {
+                if (!_url.match(/^webworks:\/\//)) {
+                    origMethods.send.apply(xhr, Array.prototype.slice.call(arguments));
+                    return;
+                }
+
+                var params = _url.match(/\?(.*)$/),
+                    objPath = _url.match(/^webworks:\/\/([^\?]*)/)[1].split("/"),
+                    apiMethod = objPath.reduce(function (obj, name) {
+                        return obj[name];
+                    }, webworks),
+                    postParams = {},
+                    get = {};
+
+                if (params) {
+                    params[1].split("&").forEach(function (param) {
+                            var pair = param.split("="),
+                                key = decodeURIComponent(pair[0]),
+                                value = decodeURIComponent(pair[1]);
+                            // parsing undefied with JSON throws exception
+                            get[key] = value === "undefined" ? undefined : JSON.parse(value);
+                        });
+                }
+
+                if (post) {
+                    post.split("&").forEach(function (param) {
+                            var pair = param.split("="),
+                                value;
+                            try {
+                                value = JSON.parse(decodeURIComponent(pair[1]));
+                            } catch (e) {
+                                value = pair[1] === "undefined" ? undefined : pair[1];
+                            }
+
+                            postParams[pair[0]] = value;
+                        });
+                }
+
+                statemachine(function (prev, baton) {
+                    return apiMethod(get, postParams, baton);
+                });
+            };
+
+            return xhr;
+        };
+    }
+};
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/client/events', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _handlers = [],
+    _self;
+
+_self = {
+    eventsMap: {
+        getHandlerById: function (handlerId) {
+            return _handlers[handlerId];
+        },
+        addHandler: function (handler) {
+            _handlers.push(handler);
+            return _handlers.length - 1;
+        },
+        removeHandler: function (handlerId) {
+            if (handlerId > -1 && handlerId < _handlers.length) {
+                delete _handlers[handlerId]; //cannot splice because all published IDs would refer to the wrong handler
+            }
+        }
+    },
+
+    registerEventHandler : function (eventName, eventCallback, eventParams) {
+        return _self.eventsMap.addHandler(eventCallback);
+    },
+
+    getEventHandler : function (handlerId) {
+        return _self.eventsMap.getHandlerById(handlerId);
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/client/FileProperties', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function FileProperties(props) {
+    props = props || {};
+
+    function _get(val) {
+        return function () {
+            return props[val];
+        };
+    }
+
+    this.__defineGetter__("dateCreated", _get("dateCreated")); //tablet only
+    this.__defineGetter__("dateModified", _get("dateModified"));
+    this.__defineGetter__("directory", _get("directory"));
+    this.__defineGetter__("fileExtension", _get("fileExtension"));
+    this.__defineGetter__("isHidden", _get("isHidden"));
+    this.__defineGetter__("isReadonly", _get("isReadonly")); //handset only
+    this.__defineGetter__("mimeType", _get("mimeType")); //handset only
+    this.__defineGetter__("size", _get("size"));
+}
+
+module.exports = FileProperties;
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/client/transport', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self;
+
+function RemoteFunctionCall(functionUri) {
+    var params = {},
+        postString = "",
+        postParams = {};
+
+    function composeUri() {
+        var uri = "webworks://" + functionUri,
+            paramCount = 1,
+            param;
+
+        for (param in params) {
+            if (params.hasOwnProperty(param)) {
+                if (paramCount === 1) {
+                    uri += "?";
+                } else {
+                    uri += "&";
+                }
+                uri += param + "=" + params[param];
+                paramCount++;
+            }
+
+            uri = uri.replace(/\&$/, "");
+        }
+
+        return uri;
+    }
+
+    function createXhrRequest(uri, isAsync) {
+        var request = new XMLHttpRequest(),
+            paramCount = 1,
+            param;
+
+        for (param in postParams) {
+            if (postParams.hasOwnProperty(param)) {
+                postString += param + "=" + postParams[param] + "&";
+                paramCount++;
+            }
+        }
+
+        postString = postString.replace(/\&$/, "");
+
+        // TODO: make get/post
+        request.open("POST", uri, isAsync);
+        request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+
+        return request;
+    }
+
+    this.addParam = function (name, value) {
+        params[name] = encodeURIComponent(JSON.stringify(value));
+    };
+
+    this.addPostParam = function (name, value) {
+        postParams[name] = encodeURIComponent(JSON.stringify(value));
+    };
+
+    this.makeSyncCall = function (success, error) {
+        var requestUri = composeUri(),
+            request = createXhrRequest(requestUri, false),
+            response, errored, cb, data;
+
+        request.send(postString);
+
+        response = JSON.parse(request.responseText || "null");
+        errored = response.code < 0;
+        cb = errored ? error : success;
+        data = errored ? response.msg : response.data;
+
+        if (cb) {
+            cb(data, response);
+        }
+        else if (errored) {
+            throw data;
+        }
+
+        return data;
+    };
+
+    this.makeAsyncCall = function (success, error) {
+        var requestUri = composeUri(),
+            request = createXhrRequest(requestUri, true);
+
+        request.onreadystatechange = function () {
+            if (request.readyState === 4 && request.status === 200) {
+                var response = JSON.parse(request.responseText || "null"),
+                    cb = response.code < 0 ? error : success,
+                    data = response.code < 0 ? response.msg : response.data;
+
+                return cb && cb(data, response);
+            }
+        };
+
+        request.send(postString);
+    };
+}
+
+_self = {
+    call: function (url, opts, success, error) {
+        var request = new RemoteFunctionCall(url),
+            name;
+
+        opts = opts || {};
+
+        if (opts.get) {
+            for (name in opts.get) {
+                if (Object.hasOwnProperty.call(opts.get, name)) {
+                    request.addParam(name, opts.get[name]);
+                }
+            }
+        }
+
+        if (opts.post) {
+            for (name in opts.post) {
+                if (Object.hasOwnProperty.call(opts.post, name)) {
+                    request.addPostParam(name, opts.post[name]);
+                }
+            }
+        }
+
+        return opts.async ? request.makeAsyncCall(success, error) : request.makeSyncCall(success, error);
+    },
+
+    poll: function (url, opts, callback) {
+        opts = opts || {};
+        opts.async = true;
+
+        _self.call(url, opts, function (data, response) {
+            if (callback(data, response)) {
+                _self.poll(url, opts, callback);
+            }
+        });
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/client/io/dir', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/io/dir/",
+    FILE = "file://";
+
+function _prunePrefix(path) {
+    return path.replace(new RegExp("^" + FILE), '');
+}
+
+function _addPrefix(path) {
+    return FILE + path;
+}
+
+module.exports = {
+    createNewDir: function (path) {
+        transport.call(_uri + "createNewDir", {
+            post: {path: _prunePrefix(path)}
+        });
+    },
+    deleteDirectory: function (path, recursive) {
+        transport.call(_uri + "deleteDirectory", {
+            post: {path: _prunePrefix(path), recursive: recursive}
+        });
+    },
+    exists: function (path) {
+        return transport.call(_uri + "exists", {
+            post: {path: _prunePrefix(path)}
+        });
+    },
+    getParentDirectory: function (path) {
+        return _addPrefix(transport.call(_uri + "getParentDirectory", {
+            post: {path: _prunePrefix(path)}
+        }));
+    },
+    listDirectories: function (path) {
+        return transport.call(_uri + "listDirectories", {
+            post: {path: _prunePrefix(path)}
+        });
+    },
+    listFiles: function (path) {
+        return transport.call(_uri + "listFiles", {
+            post: {path: _prunePrefix(path)}
+        });
+    },
+    rename: function (path, newName) {
+        transport.call(_uri + "rename", {
+            post: {path: _prunePrefix(path), newName: newName}
+        });
+    }
+};
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/client/io/file', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/io/file/",
+    FILE = "file://",
+    _onFileOpened;
+
+function _prunePrefix(path) {
+    return path.replace(new RegExp("^" + FILE), '');
+}
+
+module.exports = {
+    copy: function (from, to) {
+        transport.call(_uri + "copy", {
+            post: {from: _prunePrefix(from), to: _prunePrefix(to)}
+        });
+    },
+    deleteFile: function (path) {
+        transport.call(_uri + "deleteFile", {
+            post: {path: _prunePrefix(path)}
+        });
+    },
+    exists: function (path) {
+        return transport.call(_uri + "exists", {
+            post: {path: _prunePrefix(path)}
+        });
+    },
+    getFileProperties: function (path) {
+        var properties = transport.call(_uri + "getFileProperties", {
+            post: {path: _prunePrefix(path)}
+        });
+        properties.directory = FILE + properties.directory;
+        return properties;
+    },
+    open: function (path, newName) {
+        transport.call(_uri + "open", {
+            post: {path: _prunePrefix(path)}
+        });
+    },
+    readFile: function (path, onFileOpened, async) {
+        async = async === false ? false : true;
+
+        var uri = _uri + "readFile",
+            args = {
+                post: {path: _prunePrefix(path), async: async}
+            },
+            callResult;
+
+        _onFileOpened = onFileOpened;
+
+        if (async) {
+            transport.poll(uri, args, function (data, res) {
+                if (_onFileOpened) {
+                    _onFileOpened(FILE + data.fullPath, data.blobData);
+                }
+                return false;
+            });
+        } else {
+            callResult = transport.call(uri, args);
+            _onFileOpened(FILE + callResult.fullPath, callResult.blobData);
+        }
+    },
+    rename: function (path, newName) {
+        transport.call(_uri + "rename", {
+            post: {path: _prunePrefix(path), newName: newName}
+        });
+    },
+    saveFile: function (path, blob) {
+        transport.call(_uri + "saveFile", {
+            post: {path: _prunePrefix(path), blob: blob}
+        });
+    }
+};
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/client/system', function (require, module, exports) {
+/*\r
+ *  Copyright 2011 Research In Motion Limited.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
+    _uri = "blackberry/system/",\r
+    _self;\r
+\r
+_self = {\r
+    hasCapability: function (capability) {\r
+        return transport.call(_uri + "hasCapability", {\r
+            get: {capability: capability}\r
+        });\r
+    },\r
+\r
+    hasDataCoverage: function () {\r
+        return transport.call(_uri + "hasDataCoverage");\r
+    },\r
+\r
+    hasPermission: function (desiredModule) {\r
+        return transport.call(_uri + "hasPermission", {\r
+            get: {desiredModule: desiredModule}\r
+        });\r
+    },\r
+\r
+    isMassStorageActive: function () {\r
+        return transport.call(_uri + "isMassStorageActive");\r
+    }\r
+};\r
+\r
+_self.__defineGetter__("model", function () {\r
+    return transport.call(_uri + "model");\r
+});\r
+_self.__defineGetter__("scriptApiVersion", function () {\r
+    return transport.call(_uri + "scriptApiVersion");\r
+});\r
+_self.__defineGetter__("softwareVersion", function () {\r
+    return transport.call(_uri + "softwareVersion");\r
+});\r
+\r
+_self.__defineGetter__("ALLOW", function () {\r
+    return 0;\r
+});\r
+_self.__defineGetter__("DENY", function () {\r
+    return 1;\r
+});\r
+_self.__defineGetter__("PROMPT", function () {\r
+    return 2;\r
+});\r
+_self.__defineGetter__("NOT_SET", function () {\r
+    return 3;\r
+});\r
+\r
+module.exports = _self;\r
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/client/utils', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _blobs = {};
+
+function _blobBuilder() {
+    var BlobBuilder = BlobBuilder || WebKitBlobBuilder;
+    return new BlobBuilder();
+}
+
+module.exports = {
+    parseURL: function (theUrl) {
+        /********START IDEA BORROWING*******/
+        // parseUri 1.2.2
+        // (c) Steven Levithan <stevenlevithan.com>
+        // MIT License
+
+        function parseUri(str) {
+            var        o   = parseUri.options,
+                m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+                uri = {},
+                i   = 14;
+
+            while (i--) {
+                uri[o.key[i]] = m[i] || "";
+            }
+
+            uri[o.q.name] = {};
+            uri[o.q.arrayName] = [];
+            uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+                if ($1) {
+                    uri[o.q.name][$1] = $2;
+                    uri[o.q.arrayName].push($2);
+                }
+            });
+
+            return uri;
+        }
+
+        parseUri.options = {
+                strictMode: false,
+                key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"],
+                q:   {
+                    name:   "queryKey",
+                    arrayName:   "queryArray",
+                    parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+                },
+                parser: {
+                    strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+                    loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+                }
+            };
+        /********END IDEA BORROWING*******/
+
+        parseUri.strictMode = "strict";
+        var uri = parseUri(theUrl),
+            retVal = {
+                getURLParameter : function (key) {
+                    return uri.queryKey[key];
+                },
+
+                getURLParameterByIndex : function (index) {
+                    return uri.queryArray[index];
+                }
+            };
+
+        //Add default values for the http/https port if they weren't specified in the URL. The above parser returns undefined. We need the values
+        //to be compatible with the BB version of API.
+        if (uri["port"] === "") {
+            if (uri["protocol"] === "http") {
+                uri["port"] = "80";
+            }
+            else if (uri["protocol"] === "https") {
+                uri["port"] = "443";
+            }
+            else {
+                uri["port"] = "0";
+            }
+        }
+
+        retVal.__defineGetter__("host", function () {
+            return uri["host"];
+        });
+        retVal.__defineGetter__("port", function () {
+            return parseInt(uri["port"], 10);
+        });
+
+        return retVal;
+    },
+
+    generateUniqueId: function () {
+        return Math.floor(Math.random() * Number.MAX_VALUE);
+    },
+
+    blobToString: function (blob, encoding) {
+        return _blobs[blob.id];
+    },
+
+    stringToBlob: function (string, encoding) {
+        var id = Math.uuid(undefined, 16),
+            blob = _blobBuilder(),
+            finalBlob;
+
+        _blobs[id] = string;
+        blob.append(string);
+
+        finalBlob = blob.getBlob();
+        finalBlob.id = id;
+        finalBlob.length = finalBlob.size;
+
+        return finalBlob;
+    }
+};
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/spec/events', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event');
+
+module.exports = {
+    "app.event.onBackground": {
+        callback: function () {
+            event.trigger("AppRequestBackground");
+        }
+    },
+    "app.event.onForeground": {
+        callback: function () {
+            event.trigger("AppRequestForeground");
+        }
+    }
+};
+
+});
+require.define('ripple/platform/webworks.core/2.0.0/spec/config', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils');
+
+module.exports = {
+    fileName: "config.xml",
+    validateVersion: function (config) {
+        return true;
+    },
+    extractInfo: function (config) {
+        if (!config) {
+            return null;
+        }
+
+        var widgetInfo = {},
+            widgetFeatures = config.widget.children.feature.validationResult,
+            accessUrls = config.widget.children.access.validationResult,
+            accessFeatures = config.widget.children.access.children.feature.validationResult,
+            toFeature = function (validationResult) {
+                return {
+                    id: validationResult.attributes.id.value,
+                    required: !validationResult.attributes.required || validationResult.attributes.required.value,
+                    URIs: []
+                };
+            };
+
+        widgetInfo.id = config.widget.validationResult[0].attributes.id.value;
+        widgetInfo.name = config.widget.children.name.validationResult[0].value;
+        widgetInfo.icon = config.widget.children.icon.validationResult[0].attributes.src.value;
+        widgetInfo.version = config.widget.validationResult[0].attributes.version.value;
+        widgetInfo.author = config.widget.children.author.validationResult[0].value;
+        widgetInfo.authorEmail = config.widget.children.author.validationResult[0].attributes.email.value;
+        widgetInfo.authorURL = config.widget.children.author.validationResult[0].attributes.href.value;
+        widgetInfo.copyright = config.widget.children.author.validationResult[0].attributes["rim:copyright"].value;
+        widgetInfo.description = config.widget.children.description.validationResult[0].value;
+        if (config.widget.children.license.validationResult[0]) {
+            widgetInfo.license = config.widget.children.license.validationResult[0].value;
+            widgetInfo.licenseURL = config.widget.children.license.validationResult[0].attributes.href.value;
+        }
+
+        widgetInfo.features = widgetFeatures.reduce(function (features, validationResult) {
+            if (validationResult.valid) {
+                var feature = toFeature(validationResult);
+                feature.URIs.push({
+                    value: utils.location().href,
+                    subdomains: true
+                });
+                features = features || {};
+                features[feature.id] = feature;
+            }
+            return features;
+        }, {});
+
+        widgetInfo.features = accessUrls.map(function (access) {
+            return {
+                uri: access.attributes.uri.value,
+                subdomains: access.attributes.subdomains.value,
+                features: accessFeatures ? accessFeatures.filter(function (f) {
+                    return f.node && f.node.parentNode && f.node.parentNode.attributes.uri.value === access.attributes.uri.value;
+                }) : null
+            };
+        }).reduce(function (result, access) {
+            return access.features ? access.features.reduce(function (features, validationResult) {
+                var feature = features[validationResult.attributes.id.value] || toFeature(validationResult);
+                feature.URIs.push({
+                    value: access.uri,
+                    subdomains: access.subdomains
+                });
+                features[feature.id] = feature;
+                return features;
+            }, result) : result;
+        }, widgetInfo.features);
+
+        return widgetInfo;
+    },
+    schema: {
+        rootElement: "widget",
+        widget: {
+            nodeName: "widget",
+            required: true,
+            occurrence: 1,
+            attributes: {
+                xmlns: {
+                    attributeName: "xmlns",
+                    required: true,
+                    type: "list",
+                    listValues: ["http://www.w3.org/ns/widgets"]
+                },
+                "xmlns:rim": {
+                    attributeName: "xmlns:rim",
+                    required: true,
+                    type: "list",
+                    listValues: ["http://www.blackberry.com/ns/widgets"]
+                },
+                "xml:lang": {
+                    attributeName: "xml:lang",
+                    required: false,
+                    type: "iso-language"
+                },
+                id: {
+                    attributeName: "id",
+                    required: false,
+                    type: "string"
+                },
+                version: {
+                    attributeName: "version",
+                    required: false,
+                    type: "string"
+                },
+                "rim:header": {
+                    attributeName: "rim:header",
+                    required: false,
+                    type: "string"
+                },
+                "rim:backButton": {
+                    attributeName: "rim:backButton",
+                    required: false,
+                    type: "string"
+                }
+            },
+            children: {
+                name: {
+                    nodeName: "name",
+                    required: true,
+                    occurrence: 1,
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language"
+                        },
+                        "its:dir": {
+                            attributeName: "its:dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["rtl", "ltr", "lro", "rlo"]
+                        }
+                    }
+                },
+                description: {
+                    nodeName: "description",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language"
+                        },
+                        "its:dir": {
+                            attributeName: "its:dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["rtl", "ltr", "lro", "rlo"]
+                        }
+                    }
+                },
+                icon: {
+                    nodeName: "icon",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        src: {
+                            attributeName: "src",
+                            type: "string",
+                            required: true
+                        },
+                        "rim:hover": {
+                            attributeName: "rim:hover",
+                            type: "boolean",
+                            required: false
+                        }
+                    }
+                },
+                author: {
+                    nodeName: "author",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        href: {
+                            attributeName: "href",
+                            type: "string",
+                            required: false
+                        },
+                        "rim:copyright": {
+                            attributeName: "rim:copyright",
+                            type: "string",
+                            required: false
+                        },
+                        email: {
+                            attributeName: "email",
+                            type: "string",
+                            required: false
+                        },
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language"
+                        },
+                        "its:dir": {
+                            attributeName: "its:dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["rtl", "ltr", "lro", "rlo"]
+                        }
+                    }
+                },
+                license: {
+                    nodeName: "license",
+                    required: false,
+                    occurrence: 1,
+                    attributes : {
+                        href: {
+                            attributeName: "href",
+                            type: "string",
+                            required: false
+                        },
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language"
+                        },
+                        "its:dir": {
+                            attributeName: "its:dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["rtl", "ltr", "lro", "rlo"]
+                        }
+                    }
+                },
+                "rim:cache": {
+                    nodeName: "rim:cache",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        disableAllCache: {
+                            attributeName: "disableAllCache",
+                            required: false,
+                            type: "boolean"
+                        },
+                        aggressiveCacheAge: {
+                            attributeName: "aggressiveCacheAge",
+                            required: false,
+                            type: "number"
+                        },
+                        maxCacheSizeTotal: {
+                            attributeName: "maxCacheSizeTotal",
+                            required: false,
+                            type: "number"
+                        },
+                        maxCacheSizeItem: {
+                            attributeName: "maxCacheSizeItem",
+                            required: false,
+                            type: "number"
+                        }
+                    }
+                },
+                access: {
+                    nodeName: "access",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        uri: {
+                            attributeName: "uri",
+                            required: true,
+                            type: "string"
+                        },
+                        subdomains: {
+                            attributeName: "subdomains",
+                            required: false,
+                            type: "boolean"
+                        }
+                    },
+                    children: {
+                        feature: {
+                            nodeName: "feature",
+                            required: false,
+                            occurrence: 0,
+                            attributes: {
+                                id: {
+                                    attributeName: "id",
+                                    required: true,
+                                    //TODO: this should be a list
+                                    type: "string"
+                                },
+                                required: {
+                                    attributeName: "required",
+                                    required: false,
+                                    type: "boolean"
+                                },
+                                version: {
+                                    attributeName: "version",
+                                    required: false,
+                                    type: "string"
+                                }
+                            }
+                        }
+                    }
+                },
+                feature: {
+                    nodeName: "feature",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        id: {
+                            attributeName: "id",
+                            required: true,
+                            //TODO: this should be a list
+                            type: "string"
+                        },
+                        required: {
+                            attributeName: "required",
+                            required: false,
+                            type: "boolean"
+                        },
+                        version: {
+                            attributeName: "version",
+                            required: false,
+                            type: "string"
+                        }
+                    }
+                },
+                "rim:loadingScreen": {
+                    nodeName: "rim:loadingScreen",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        backgroundColor: {
+                            attributeName: "backgroundColor",
+                            required: false,
+                            type: "string"
+                        },
+                        backgroundImage: {
+                            attributeName: "backgroundImage",
+                            required: false,
+                            type: "string"
+                        },
+                        foregroundImage: {
+                            attributeName: "foregroundImage",
+                            required: false,
+                            type: "string"
+                        },
+                        onRemotePageLoad: {
+                            attributeName: "onRemotePageLoad",
+                            required: false,
+                            type: "boolean"
+                        },
+                        onLocalPageLoad: {
+                            attributeName: "onLocalPageLoad",
+                            required : false,
+                            type: "boolean"
+                        },
+                        onFirstLaunch: {
+                            attributeName: "onFirstLaunch",
+                            required: false,
+                            type: "boolean"
+                        }
+                    },
+                    children: {
+                        "rim:transitionEffect": {
+                            nodeName: "rim:transitionEffect",
+                            required: false,
+                            occurrence: 1,
+                            attributes: {
+                                "type": {
+                                    attributeName: "type",
+                                    required: true,
+                                    type: "list",
+                                    listValues: ["slidePush", "slideOver", "fadeIn", "fadeOut", "wipeIn", "wipeOut", "zoomIn", "zoomOut"]
+                                },
+                                duration: {
+                                    attributeName: "duration",
+                                    required: false,
+                                    type: "number"
+                                },
+                                direction: {
+                                    attributeName: "direction",
+                                    required: false,
+                                    type: "list",
+                                    listValues: ["left", "right", "up", "down"]
+                                }
+                            }
+                        }
+                    }
+                },
+                "rim:connection": {
+                    nodeName: "rim:connection",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        timeout: {
+                            attributeName: "timeout",
+                            required: false,
+                            type: "number"
+                        }
+                    },
+                    children: {
+                        id: {
+                            nodeName: "id",
+                            required: false,
+                            occurrence: 0
+                        }
+                    }
+                },
+                "rim:navigation": {
+                    nodeName: "rim:navigation",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        mode: {
+                            attributeName: "mode",
+                            required: false,
+                            type: "list",
+                            listValues: ["focus"]
+                        }
+                    }
+                },
+                "content": {
+                    nodeName: "content",
+                    required: true,
+                    occurrence: 1,
+                    attributes: {
+                        src: {
+                            attributeName: "src",
+                            required: true,
+                            type: "string"
+                        },
+                        type: {
+                            attributeName: "type",
+                            required: false,
+                            type: "string"
+                        },
+                        charset: {
+                            attributeName: "charset",
+                            required: false,
+                            type: "string"
+                        }
+                    }
+                }
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/platform/builder', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    app = require('ripple/app'),
+    constants = require('ripple/constants');
+
+function _objectFactory(context, objects, allowed) {
+    utils.forEach(objects, function (obj, key) {
+        var result = {}, objFeatures = {}, rst, f, widgetFeatures;
+
+        if (allowed(obj)) {
+            result = obj.path ? require('ripple/platform/' + obj.path) : {};
+            if (typeof result === "function" && obj.handleSubfeatures && obj.handleSubfeatures === true) {
+                rst = new result();
+                if (obj.feature) {
+                    objFeatures = obj.feature.split('|');
+                    if (rst.handleSubFeatures) {
+                        widgetFeatures = app.getInfo().features; // features in config.xml
+                        f = {};
+                        utils.forEach(objFeatures, function (o) {
+                            if (widgetFeatures && !!widgetFeatures[o]) {
+                                f[widgetFeatures[o].id] = widgetFeatures[o];
+                            }
+                        });
+                        rst.handleSubFeatures(f);
+                        delete rst.handleSubFeatures;
+                    }
+                }
+                result = rst;
+            }
+        }
+
+        if (obj.children) {
+            _objectFactory(result, obj.children, allowed);
+        }
+
+        // inject into the context if it is allowed or it has children that were allowed
+        if (allowed(obj) || utils.count(result)) {
+            context[key] = result;
+        }
+        else {
+            delete context[key];
+        }
+    });
+}
+
+module.exports = {
+    build: function (objects) {
+        return {
+            into: function (sandbox) {
+                var features = utils.copy(app.getInfo().features),
+                    allowed = function (obj) {
+                        var contains = function (requirements) {
+                            return requirements.split('|').some(function (feature) {
+                                return !!features[feature];
+                            });
+                        };
+                        //object is allowed if:
+                        // 1. it has no feature requirement
+                        // 2. the config file doesn't exist (features collection is null)
+                        // 3. the feature exists in the defined features
+                        return !obj.feature || !features || (features && contains(obj.feature));
+                    };
+
+                _objectFactory(sandbox, objects, allowed);
+            }
+        };
+    }
+};
+
+});
+require.define('ripple/platform/wac/2.0/orientation', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    Rotation = function (alpha, beta, gamma) {
+        return {
+            alpha: alpha || 0,
+            beta:  beta  || 0,
+            gamma: gamma || 0
+        };
+    },
+    wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
+    _rotationInfo = new Rotation(),
+    _defaultInterval = 100,
+    _watches = {},
+    _self;
+
+module.exports = _self = {
+    getCurrentOrientation: function (onSuccess, onError) {
+        function _getCurrentOrientation() {
+            setTimeout(function () {
+                onSuccess(utils.copy(_rotationInfo));
+            }, 1);
+            return null;
+        }
+
+        return wac2_utils.validateTypeMismatch(onSuccess, onError, "getCurrentOrientation", _getCurrentOrientation);
+    },
+
+    watchOrientation: function (orientationSuccess, orientationError, options) {
+        function _watchOrientation() {
+            var watchId = (new Date()).getTime() | 0,
+                watchObj = {},
+                opt = Object(options),
+                minNotificationInterval = opt.minNotificationInterval | 0,
+                orientationInterval = _defaultInterval;
+
+            if (minNotificationInterval > 0) {
+                orientationInterval = minNotificationInterval;
+            }
+
+            watchObj = {
+                onSuccess: orientationSuccess,
+                onError: orientationError,
+                interval: orientationInterval
+            };
+
+            _watches[watchId] = watchObj;
+
+            _watches[watchId].intervalId = setInterval(function () {
+                _self.getCurrentOrientation(_watches[watchId].onSuccess, _watches[watchId].onError);
+            }, _watches[watchId].interval);
+
+            return watchId;
+        }
+
+        return wac2_utils.validateTypeMismatch(orientationSuccess, orientationError, "watchOrientation", _watchOrientation);
+    },
+
+    clearWatch: function (watchId) {
+
+        var id = watchId | 0;
+        if (_watches[id]) {
+            clearInterval(_watches[id].intervalId);
+            delete(_watches[id]);
+            return null;
+        }
+
+        return undefined;
+    }
+};
+
+event.on("AccelerometerInfoChangedEvent", function (orientationInfo) {
+    _rotationInfo.alpha = orientationInfo.orientation.alpha;
+    _rotationInfo.beta  = orientationInfo.orientation.beta;
+    _rotationInfo.gamma = orientationInfo.orientation.gamma;
+});
+
+
+});
+require.define('ripple/platform/wac/2.0/accelerometer', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    Acceleration = function (x, y, z) {
+        return {
+            xAxis: x || 0,
+            yAxis: y || 0,
+            zAxis: z || 0
+        };
+    },
+    wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
+    _accelerometerInfo = new Acceleration(),
+    _defaultInterval = 100,
+    _watches = {},
+    _self;
+
+module.exports = _self = {
+    getCurrentAcceleration: function (onSuccess, onError) {
+        function _getCurrentAcceleration() {
+            setTimeout(function () {
+                onSuccess(utils.copy(_accelerometerInfo));
+            }, 1);
+            return null;
+        }
+
+        return wac2_utils.validateTypeMismatch(onSuccess, onError, "getCurrentAcceleration", _getCurrentAcceleration); 
+    },
+
+    watchAcceleration: function (accelerometerSuccess, accelerometerError, options) {
+        function _watchAcceleration() {
+            var watchId = (new Date()).getTime() | 0,
+                watchObj = {},
+                opt = Object(options),
+                minNotificationInterval = opt.minNotificationInterval | 0,
+                accelerometerInterval = _defaultInterval;
+
+            if (minNotificationInterval > 0) {
+                accelerometerInterval = minNotificationInterval;
+            }
+
+            watchObj = {
+                onSuccess: accelerometerSuccess,
+                onError: accelerometerError,
+                interval: accelerometerInterval
+            };
+
+            _watches[watchId] = watchObj;
+
+            _watches[watchId].intervalId = setInterval(function () {
+                _self.getCurrentAcceleration(_watches[watchId].onSuccess, _watches[watchId].onError);
+            }, _watches[watchId].interval);
+
+            return watchId;
+        }
+
+        return wac2_utils.validateTypeMismatch(accelerometerSuccess, accelerometerError, "watchAcceleration", _watchAcceleration); 
+    },
+
+    clearWatch: function (watchId) {
+
+        var id = watchId | 0;
+
+        if (_watches[id]) {
+            clearInterval(_watches[id].intervalId);
+            delete(_watches[id]);
+            return null;
+        }
+
+        return undefined;
+    }
+};
+
+event.on("AccelerometerInfoChangedEvent", function (accelerometerInfo) {
+    _accelerometerInfo.xAxis = accelerometerInfo.accelerationIncludingGravity.x;
+    _accelerometerInfo.yAxis = accelerometerInfo.accelerationIncludingGravity.y;
+    _accelerometerInfo.zAxis = accelerometerInfo.accelerationIncludingGravity.z;
+});
+
+
+});
+require.define('ripple/platform/wac/2.0/geolocation', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var geo = require('ripple/geo'),
+    Position = require('ripple/platform/w3c/1.0/Position'),
+    PositionError = require('ripple/platform/w3c/1.0/PositionError'),
+    _lastPosition = null,
+    _watches = {},
+    _defaultInterval = 100,
+    _defaultDelay = 50,
+    _self;
+
+function _createPosition() {
+    var position = new Position(),
+        positionInfo = geo.getPositionInfo();
+
+    position.coords.latitude = positionInfo.latitude;
+    position.coords.longitude = positionInfo.longitude;
+    position.coords.altitude = positionInfo.altitude;
+    position.coords.altitudeAccuracy = positionInfo.altitudeAccuracy;
+    position.coords.accuracy = positionInfo.accuracy;
+    position.coords.heading = positionInfo.heading;
+    position.coords.speed = positionInfo.speed;
+    position.timestamp = positionInfo.timeStamp.getTime();
+
+    return position;
+}
+
+function _isValid(onSuccess, onError, options, argLength) {
+    if (argLength < 1 || argLength > 3)
+        return false;
+
+    if (typeof onSuccess !== "function")   // imply onSuccess == null
+        return false;
+
+    if (onError && (typeof onError !== "function"))
+        return false;
+
+    if ((options !== undefined) &&
+        ((typeof options !== "object") ||
+        (options.enableHighAccuracy !== undefined) && (typeof options.enableHighAccuracy !== "boolean") ||
+        (options.timeout            !== undefined) && (typeof options.timeout            !== "number") ||
+        (options.maximumAge         !== undefined) && (typeof options.maximumAge         !== "number")))
+        return false;
+
+    return true;
+}
+
+function _processOptions(options) {
+    var validOptions = {
+        enableHighAccuracy: false,
+        timeout: 0,
+        maximumAge: 0
+    };
+
+    if (options !== undefined &&
+        options.maximumAge !== undefined &&
+        options.maximumAge === Math.floor(options.maximumAge) &&
+        options.maximumAge >= 0) {
+        validOptions.maximumAge = options.maximumAge | 0;
+    } else {
+        validOptions.maximumAge = 0;
+    }
+
+    if (options !== undefined &&
+        options.timeout !== undefined &&
+        options.timeout === Math.floor(options.timeout)) {
+        validOptions.timeout = (options.timeout >= 0) ? (options.timeout | 0) : 0;
+    } else {
+        validOptions.timeout = Infinity;
+    }
+
+    if (options !== undefined && options.enableHighAccuracy !== undefined) {
+        validOptions.enableHighAccuracy = options.enableHighAccuracy;
+    } else {
+        validOptions.enableHighAccuracy = false;
+    }
+
+    validOptions.delay = geo.delay * 1000 || _defaultDelay;
+
+    return validOptions;
+}
+
+function _errorOccur(code, onError) {
+    if (!onError)
+        return;
+
+    var error = new PositionError();
+
+    error.code = code;
+    switch (code) {
+    case PositionError.POSITION_UNAVAILABLE:
+        error.message = "Position unavailable";
+        break;
+
+    case PositionError.TIMEOUT:
+        error.message = "Position timed out";
+        break;
+    }
+
+    onError(error);
+}
+
+function _execute(data) {
+    return function () {
+        if (_lastPosition !== null &&
+            ((new Date()).getTime() - _lastPosition.timestamp <= data.maximumAge)) {
+            window.setTimeout(function () {
+                data.onSuccess(_lastPosition);
+            }, 1);
+        } else if (data.timeout === 0) {
+            _errorOccur(PositionError.TIMEOUT, data.onError);
+        } else {
+            window.setTimeout(function () {
+                if (data.delay <= data.timeout) {
+                    _lastPosition = _createPosition();
+
+                    if (_lastPosition !== null) {
+                        data.onSuccess(_lastPosition);
+                    } else {
+                        _errorOccur(PositionError.POSITION_UNAVAILABLE, data.onError);
+                    }
+                } else {
+                    _errorOccur(PositionError.TIMEOUT, data.onError);
+                }
+            }, Math.min(data.delay, data.timeout));
+        }
+    };
+}
+
+function _interval(k, n) { 
+    return k * Math.floor((n + k - 1) / k) || k;
+}
+
+_self = {
+    getCurrentPosition: function (onSuccess, onError, options) {
+        if (!_isValid(onSuccess, onError, options, arguments.length))
+            return;
+
+        var validData = _processOptions(options);
+
+        validData.onSuccess = onSuccess;
+        validData.onError   = onError;
+
+        _execute(validData)();
+    },
+
+    watchPosition: function (geolocationSuccess, geolocationError, geolocationOptions) {
+        if (!_isValid(geolocationSuccess, geolocationError, geolocationOptions, arguments.length))
+            return undefined;
+
+        var validData = _processOptions(geolocationOptions),
+            watchId = (new Date()).getTime() | 0,
+            watchObj = {
+                onSuccess:          geolocationSuccess,
+                onError:            geolocationError,
+                enableHighAccuracy: validData.enableHighAccuracy,
+                timeout:            validData.timeout,
+                maximumAge:         validData.maximumAge,
+                delay:              validData.delay,
+                interval:           _interval(validData.maximumAge || _defaultInterval,
+                                        Math.min(validData.delay, validData.timeout)),
+            };
+
+        _watches[watchId] = watchObj;
+
+        _watches[watchId].intervalId = window.setInterval(_execute(_watches[watchId]),
+            _watches[watchId].interval);
+
+        return watchId;
+    },
+
+    clearWatch: function (watchId) {
+        if (arguments.length !== 1)
+            return undefined;
+
+        var id = watchId | 0;
+
+        if (_watches[id]) {
+            window.clearInterval(_watches[id].intervalId);
+            delete _watches[id];
+
+            return null;
+        }
+
+        return undefined;
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/2.0/errorcode', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var _self = {
+    message : []
+};
+
+_self.__defineGetter__("UNKNOWN_ERR", function () {
+    return 0;
+});
+
+_self.__defineGetter__("INDEX_SIZE_ERR", function () {
+    return 1;
+});
+
+_self.__defineGetter__("DOMSTRING_SIZE_ERR", function () {
+    return 2;
+});
+
+_self.__defineGetter__("HIERARCHY_REQUEST_ERR", function () {
+    return 3;
+});
+
+_self.__defineGetter__("WRONG_DOCUMENT_ERR", function () {
+    return 4;
+});
+
+_self.__defineGetter__("INVALID_CHARACTER_ERR", function () {
+    return 5;
+});
+
+_self.__defineGetter__("NO_DATA_ALLOWED_ERR", function () {
+    return 6;
+});
+
+_self.__defineGetter__("NO_MODIFICATION_ALLOWED_ERR", function () {
+    return 7;
+});
+
+_self.__defineGetter__("NOT_FOUND_ERR", function () {
+    return 8;
+});
+
+_self.__defineGetter__("NOT_SUPPORTED_ERR", function () {
+    return 9;
+});
+
+_self.__defineGetter__("INUSE_ATTRIBUTE_ERR", function () {
+    return 10;
+});
+
+_self.__defineGetter__("INVALID_STATE_ERR", function () {
+    return 11;
+});
+
+_self.__defineGetter__("SYNTAX_ERR", function () {
+    return 12;
+});
+
+_self.__defineGetter__("INVALID_MODIFICATION_ERR", function () {
+    return 13;
+});
+
+_self.__defineGetter__("NAMESPACE_ERR", function () {
+    return 14;
+});
+
+_self.__defineGetter__("INVALID_ACCESS_ERR", function () {
+    return 15;
+});
+
+_self.__defineGetter__("VALIDATION_ERR", function () {
+    return 16;
+});
+
+_self.__defineGetter__("TYPE_MISMATCH_ERR", function () {
+    return 17;
+});
+
+_self.__defineGetter__("SECURITY_ERR", function () {
+    return 18;
+});
+
+_self.__defineGetter__("NETWORK_ERR", function () {
+    return 19;
+});
+
+_self.__defineGetter__("ABORT_ERR", function () {
+    return 20;
+});
+
+_self.__defineGetter__("TIMEOUT_ERR", function () {
+    return 21;
+});
+
+_self.__defineGetter__("INVALID_VALUES_ERR", function () {
+    return 22;
+});
+
+_self.__defineGetter__("IO_ERR", function () {
+    return 100;
+});
+
+_self.__defineGetter__("NOT_AVAILABLE_ERR", function () {
+    return 101;
+});
+
+function _setMessage(_self) {
+    var c, g;
+    for (c in _self) {
+        g = _self.__lookupGetter__(c);
+        if (g) {
+            _self.message[g()] = c;
+        }
+    }
+}
+
+_setMessage(_self);
+
+module.exports = _self;
+
+
+});
+require.define('ripple/platform/wac/2.0/contactfilter', function (require, module, exports) {
+/*\r
+ *  Copyright 2011 Intel Corporation.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+var utils = require('ripple/utils'),\r
+    _self;\r
+\r
+_self = function (criteria) {\r
+    var pattern,\r
+        contactFilter;\r
+\r
+    contactFilter = {\r
+        match: function (target) {\r
+            var result = false, key, value, index;\r
+\r
+            switch (Object.prototype.toString.call(target)) {\r
+            case "[object String]":\r
+                result = pattern.test(target);\r
+                break;\r
+\r
+            case "[object Object]":\r
+                for (key in criteria) {\r
+                    result = true;\r
+                    value = criteria[key];\r
+                    if ((value !== undefined) && (!_self(value).match(target[key])))\r
+                        return false;\r
+                }\r
+                break;\r
+\r
+            case "[object Array]":\r
+                for (index in target) {\r
+                    if (contactFilter.match(target[index]))\r
+                        return true;\r
+                }\r
+                break;\r
+            }\r
+\r
+            return result;\r
+        }\r
+    };\r
+\r
+    if (typeof criteria === "string")\r
+        pattern = new RegExp(criteria.replace(/(^|[^\\])%+/g, "$1.*").replace(/\\%/g, "%").replace(/.*/, "^$&$"), "i");\r
+\r
+    return contactFilter;\r
+};\r
+\r
+module.exports = _self;\r
+
+});
+require.define('ripple/platform/wac/2.0/filesystem', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var errorcode = require('ripple/platform/wac/2.0/errorcode'),
+    DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
+    utils = require('ripple/utils'),
+    dbfs  = require('ripple/platform/wac/2.0/dbfs'),
+    wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
+    _console = require('ripple/console'),
+    _maxPathLength = 256,
+    _virtualRoots = ["documents", "images", "music", "videos", "downloads", "wgt-package", "wgt-private", "wgt-private-tmp", "removable", "attachments"],
+    _realRoots = dbfs.roots,
+    _r2vmap = {},
+    _v2rmap = {},
+    _initialized = false,
+    _readOnly  = false,
+    _writeOnly = false,
+    _defaultMode = "rw",
+    File, 
+    FileStream;
+
+function _isValidChar(c) {
+    return  (c >= '0' && c <= '9') || 
+        (c >= 'a' && c <= 'z') || 
+        (c >= 'A' && c <= 'Z') || 
+        (c === ' ') || 
+        (c === '_') ||
+        (c === '-') ||
+        (c === '.');
+}
+
+function _isValidFileName(name) {
+    var _valid = true,
+        _c;
+
+    if (name === '' || name === '.' || name === '..' || (name.length > _maxPathLength)) {
+        _valid = false;
+    } else {
+        for (_c = 0; _c < name.length; _c++) {
+            if (!_isValidChar(name[_c])) {
+                _valid = false;
+                break;
+            }
+        }
+    }
+    
+    return _valid;
+}
+
+function _initialize() {
+    var _i;
+
+    dbfs.initialize();
+    
+    // set up the map between real path and virtual path
+    for (_i = 0; _i < _virtualRoots.length; _i++) {
+        _r2vmap[_realRoots[_i]] = _virtualRoots[_i];
+    }
+
+    utils.forEach(_r2vmap, function (value, key) {
+        _v2rmap[value] = key;
+    });
+}
+
+function _resolveSync(srcLocation, onSuccess, onError, accessMode) {
+    var _parts = srcLocation.replace(/\/$/, '').split("/"),
+        _header, _fullPath,
+        _i;
+
+    // TODO: Initialize at bootstrap and emulatorBridge.link 
+    if (!_initialized) {
+        _initialize();
+        _initialized = true;
+    }
+
+    for (_i = 0; _i < _parts.length; _i++) {
+        if (!_isValidFileName(_parts[_i])) {
+            if (onError) {
+                onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+            }
+            return;
+        }
+    }
+
+    _header = _v2rmap[_parts[0]];
+    if (_header === undefined) {
+        if (onError) {
+            onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
+        }
+        return;
+    }
+
+    if (_parts.length === 1) {
+        _fullPath = _header;
+    } else {
+        _fullPath = _header + "/" + _parts.splice(1, _parts.length - 1).join("/");
+    }
+
+    dbfs.stat(_fullPath, 
+            function (entry) {
+                onSuccess(new File(entry, accessMode));
+            }, 
+            function () {
+                if (onError) {
+                    onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
+                }    
+            });
+}
+
+function _resolveAsync(onSuccess, onError, srcLocation, accessMode) {
+    _resolveSync(srcLocation,
+                function (file) {
+                    setTimeout(function () {
+                        onSuccess(file);
+                    }, 1);
+                },
+                function (e) {
+                    setTimeout(function () {
+                        onError(e);
+                    }, 1);
+                },
+                accessMode);
+}
+
+File = function (entry, mode) {
+    var _entry = entry,
+        _mode = mode,
+        _parent,
+        _self;
+
+    function _r2v(rpath) {
+        var i, v, r, regExp;
+
+        for (i = 0; i < _virtualRoots.length; i++) {
+            v = _virtualRoots[i];
+            r = _v2rmap[v];
+            if (rpath.match("^" + r)) {
+                regExp = new RegExp("^" + r);
+                return rpath.replace(regExp, v);
+            }
+        }
+
+        return ""; 
+    }
+
+    function _v2r(vpath) {
+        var i, v, r, regExp;
+
+        for (i = 0; i < _virtualRoots.length; i++) {
+            v = _virtualRoots[i];
+            r = _v2rmap[v];
+            if (vpath.match("^" + v)) {
+                regExp = new RegExp("^" + v);
+                return vpath.replace(regExp, r);
+            }
+        }
+
+        return ""; 
+    }
+
+    function _copyMoveInternal(onSuccess, onError, src, dst, overwrite, func) {
+        var _srcName = String(src),
+            _dstName = String(dst),
+            _src = null,
+            _dst = null,
+            _error = false,
+            _dstParent = null,
+            _dstParts  = _dstName.split("/"),
+            _dstParentName = _dstParts.splice(0, _dstParts.length - 1).join("/");
+
+        if (!_entry.isDirectory) {
+            if (onError) {
+                setTimeout(function () {
+                    onError(new DeviceApiError(errorcode.IO_ERR));
+                }, 1);
+            }
+            return undefined;
+        }
+
+        _resolveSync(_srcName, 
+                function (file) {
+                    _src = file;
+                },
+                function (e) {
+                    setTimeout(function () {
+                        onError(e);
+                    }, 1);
+                },
+                _mode);
+
+        if (_src) {
+            if (_src.parent.fullPath === _self.fullPath) {
+                if (!_readOnly && _mode !== "r") {
+                    _resolveSync(_dstParentName, 
+                            function (file) {
+                                _dstParent = file;
+                            },
+                            function (e) {
+                                setTimeout(function () {
+                                    onError(e);
+                                }, 1);
+                            },
+                            _mode);
+
+                    if (_dstParent === null) {
+                        return undefined;
+                    }
+
+                    _resolveSync(_dstName, 
+                            function (file) {
+                                _dst = file;
+                            },
+                            function (e) {
+                                if (e.code !== errorcode.NOT_FOUND_ERR) {
+                                    setTimeout(function () {
+                                        onError(e);
+                                    }, 1);
+                                    _error = true;
+                                } 
+                            },
+                            _mode);
+
+                    if (_error) {
+                        return undefined;
+                    }
+
+                    if (_src.isFile) {
+                        if (_dst === null) {
+                            func(_v2r(_srcName), _v2r(_dstName),
+                                    function () {
+                                        setTimeout(function () {
+                                            onSuccess();
+                                        }, 1);
+                                    },
+                                    function () {});
+                            return null;
+                        } else {
+                            if (_dst.isFile && Boolean(overwrite) && (_srcName !== _dstName)) {
+                                func(_v2r(_srcName), _v2r(_dstName),
+                                        function () {
+                                            setTimeout(function () {
+                                                onSuccess();
+                                            }, 1);
+                                        },
+                                        function () {});
+                                return null;
+                            } else {
+                                setTimeout(function () {
+                                    onError(new DeviceApiError(errorcode.IO_ERR));
+                                }, 1);
+                            }
+                        }
+                    } else {
+                        if (_dst === null) {
+                            func(_v2r(_srcName), _v2r(_dstName),
+                                function () {
+                                    setTimeout(function () {
+                                        onSuccess();
+                                    }, 1);
+                                },
+                                function () {});
+                            return null;
+                        } else {
+                            setTimeout(function () {
+                                onError(new DeviceApiError(errorcode.IO_ERR));
+                            }, 1);
+                        } 
+                    }
+                } else {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                }
+            } else {
+                if (onError) {
+                    setTimeout(function () {
+                        onError(new DeviceApiError(errorcode.IO_ERR));
+                    }, 1);
+                }
+            }
+        }
+
+        return undefined;
+    }
+
+    _self = {
+        toURI: function () {
+            return "file://" + _entry.fullPath;
+        },
+        listFiles: function (onSuccess, onError, filter) {
+            var _filter = Object(filter),
+                _filterName = _filter.name,
+                _startModified = _filter.startModified,
+                _endModified   = _filter.endModified;
+
+            function _matchName(fileName) {
+                var _matched = true, 
+                    _name1 = String(_filterName).toLowerCase(),
+                    _name2 = fileName.toLowerCase(),
+                    _pattern;
+
+                if (_filterName !== undefined && _filterName !== null) {
+                    if (!_name1.match("\\\\%")) {
+                        if (_name1.match("%")) {
+                            _pattern = new RegExp("^" + _name1.replace(/%/g, ".*") + "$");
+                            _matched = _name2.match(_pattern) ? true : false;
+                        } else {
+                            _matched = (_name1 === _name2);
+                        }
+                    } else {
+                        // % is not allowed as a part of file name
+                        _matched = false;
+                    }
+                }
+                
+                return _matched;
+            }
+
+            function _matchDate(date) {
+                var _matched = true;
+
+                if (_startModified !== undefined && _startModified !== null) {
+                    _matched = (date.getTime() >= _startModified.getTime());
+                }
+
+                if (_matched && (_endModified !== undefined && _endModified !== null)) {
+                    _matched = (date.getTime() <= _endModified.getTime());
+                }
+
+                return _matched;
+            }
+
+            function _matchFilter(entry) {
+                return _matchName(entry.name) && _matchDate(entry.lastModifiedDate);
+            } 
+
+            function _listFiles() {
+                var _files = [];
+
+                if ((_startModified !== undefined && !wac2_utils.isValidDate(_startModified)) ||
+                    (_endModified !== undefined && !wac2_utils.isValidDate(_endModified))) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                if (!_entry.isDirectory) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.IO_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                utils.forEach(_entry.children, function (child) {
+                    if (_matchFilter(child)) {
+                        _files.push(new File(child, _mode));
+                    }
+                });
+
+                setTimeout(function () {
+                    onSuccess(_files);
+                }, 1);
+
+                return null;
+            }
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "listFiles", _listFiles);
+        },
+        openStream: function (onSuccess, onError, mode, encoding) {
+            function _openStream() {
+                var  _openMode = String(mode),
+                    _encoding = encoding ? String(encoding) : "UTF-8";
+
+                if (_openMode !== "r" && _openMode !== "w" && _openMode !== "a") {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                
+                if (((_readOnly || _mode === "r") && (_openMode === "w" || _openMode === "a")) ||
+                    (_writeOnly && _openMode === "r")) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                 
+                setTimeout(function () {
+                    onSuccess(new FileStream(_entry, _openMode, _encoding));
+                }, 1);
+
+                return null;
+            }
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "openStream", _openStream);
+        },
+        readAsText: function (onSuccess, onError, encoding) {
+            function _readAsText() {
+                var _encoding = encoding ? String(encoding) : "UTF-8";
+                if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                if (_writeOnly) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                if (_self.isFile) {
+                    dbfs.read(_entry.fullPath, 
+                            function (data) {
+                                setTimeout(function () {
+                                    onSuccess(data);
+                                }, 1);
+                            },
+                            function () {});
+                    return null;
+                } else {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.IO_ERR));
+                        }, 1);
+                    }
+                }
+
+                return undefined;
+            }
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "readAsText", _readAsText);
+        },
+        copyTo: function (onSuccess, onError, src, dst, overwrite) {
+            function _copyTo() {
+                return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.cp);
+            }
+            
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "copyTo", _copyTo);
+        },
+        moveTo: function (onSuccess, onError, src, dst, overwrite) {
+            function _moveTo() {
+                return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.mv);
+            }
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "moveTo", _moveTo);
+        },
+        createDirectory: function (dirPath) {
+            var _path  = String(dirPath),
+                _parts = _path.replace(/\/$/, "").split("/"),
+                _dir   = null,
+                _exist = null,
+                _current = _entry.fullPath,
+                _i;
+
+            function onSuccess(entry) {
+                _dir = entry;
+            }
+
+            for (_i = 0; _i < _parts.length; _i++) {
+                if (!_isValidFileName(_parts[_i])) {
+                    throw new DeviceApiError(errorcode.INVALID_VALUES_ERR);
+                }
+            }
+      
+            if (!entry.isDirectory) {
+                throw new DeviceApiError(errorcode.IO_ERR);
+            }
+
+            _exist = _parts.reduce(function (obj, token) {
+                return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
+            }, _entry);
+
+            if (_exist) {
+                throw new DeviceApiError(errorcode.IO_ERR);
+            }
+
+            if (_readOnly || _mode === "r") {
+                throw new DeviceApiError(errorcode.SECURITY_ERR);
+            }
+
+            for (_i = 0; _i < _parts.length; _i++) {
+                _current = _current + "/" + _parts[_i];
+                dbfs.mkdir(_current, onSuccess);
+            }
+            
+            return new File(_dir, _mode);
+        },
+        createFile: function (filePath) {
+            var _name = String(filePath),
+                _file = null;
+
+            if (!_isValidFileName(_name)) {
+                throw new DeviceApiError(errorcode.INVALID_VALUES_ERR);
+            }
+
+            if (!entry.isDirectory || (_entry.children && _entry.children[_name])) {
+                throw new DeviceApiError(errorcode.IO_ERR);
+            }
+
+            if (_readOnly || _mode === "r") {
+                throw new DeviceApiError(errorcode.SECURITY_ERR);
+            }
+
+            dbfs.touch(_entry.fullPath + "/" + _name,
+                        function (entry) {
+                            _file = new File(entry, _mode);
+                        },
+                        function () {});
+            
+            return _file;
+        },
+        resolve: function (filePath) {
+            var _fullPath = _self.fullPath + "/" + String(filePath),
+                _file = null;
+            if (!_entry.isDirectory) {
+                throw new DeviceApiError(errorcode.IO_ERR); 
+            }
+
+            _resolveSync(_fullPath,
+                    function (file) {
+                        _file = file;
+                    },
+                    function (e) {
+                        throw (e);
+                    },
+                    _mode);
+
+            return _file;
+        }, 
+        deleteDirectory: function (onSuccess, onError, directory, recursive) {
+            function _deleteDirectory() {
+                var _dir = null,
+                    _dirName = String(directory);
+                _resolveSync(_dirName, 
+                        function (file) {
+                            _dir = file;
+                        },
+                        function (e) {
+                            setTimeout(function () {
+                                onError(e);
+                            }, 1);
+                        },
+                        _mode);
+
+                if (_dir) {
+                    if (_dir.isDirectory && 
+                        _dir.parent.fullPath === _self.fullPath &&
+                        (!recursive && _dir.length === 0)) {
+                        if (!_readOnly && _mode !== "r") {
+                            dbfs.rmdir(_v2r(_dirName),
+                                    function () {
+                                        setTimeout(function () {
+                                            onSuccess();
+                                        }, 1);
+                                    },
+                                    function () {});
+                            return null;
+                        } else {
+                            if (onError) {
+                                setTimeout(function () {
+                                    onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                                }, 1);
+                            }
+                        }
+                    } else {
+                        if (onError) {
+                            setTimeout(function () {
+                                onError(new DeviceApiError(errorcode.IO_ERR));
+                            }, 1);
+                        }
+                    }
+                }
+
+                return undefined; 
+            }
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "deleteDirectory", _deleteDirectory);
+        },
+        deleteFile: function (onSuccess, onError, fileName) {
+            function _deleteFile() {
+                var _file = null;
+                _resolveSync(String(fileName),
+                        function (file) {
+                            _file = file;
+                        },
+                        function (e) {
+                            if (onError) {
+                                setTimeout(function () {
+                                    onError(e);
+                                }, 1);
+                            }
+                        },
+                        _mode);
+
+                if (_file) {
+                    if (_file.isFile && _file.parent.fullPath === _self.fullPath) {
+                        if (!_readOnly && _mode !== "r") {
+                            dbfs.rm(_v2r(fileName),
+                                    function () {
+                                        setTimeout(function () {
+                                            onSuccess();
+                                        }, 1);
+                                    },
+                                    function () {});
+                            return null;
+                        } else {
+                            if (onError) {
+                                setTimeout(function () {
+                                    onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                                }, 1);
+                            }
+                        }
+                    } else {
+                        if (onError) {
+                            setTimeout(function () {
+                                onError(new DeviceApiError(errorcode.IO_ERR));
+                            }, 1);
+                        }
+                    }
+                }
+
+                return undefined; 
+            }
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "deleteFile", _deleteFile);
+        }
+    };
+
+    _self.__defineGetter__("parent", function () {
+        var _parts = _self.fullPath.split("/");
+
+        if (_parent === undefined) {
+            if (_parts.length === 1) {
+                // virtual root's parent is null
+                _parent = null;
+            } else {
+                _resolveSync(_parts.splice(0, _parts.length - 1).join("/"), 
+                        function (file) {
+                            _parent = file;
+                        },
+                        function () {},
+                        _mode);
+            }
+            return _parent;
+        } else { 
+            return _parent;
+        }
+    });
+
+    _self.__defineGetter__("readOnly", function () {
+        return false;
+    });
+
+    _self.__defineGetter__("isFile", function () {
+        return !_entry.isDirectory;
+    });
+
+    _self.__defineGetter__("isDirectory", function () {
+        return _entry.isDirectory;
+    });
+
+    _self.__defineGetter__("created", function () {
+        return undefined;
+    });
+
+    _self.__defineGetter__("modified", function () {
+        if (_entry.isDirectory) {
+            return undefined;
+        } else {
+            return _entry.lastModifiedDate;
+        }
+    });
+
+    _self.__defineGetter__("path", function () {
+        var _parts = _self.fullPath.split("/");
+
+        if (_parts.length === 1) {
+            // virtual root
+            return _parts.join("");
+        } else {
+            return _parts.splice(0, _parts.length - 1).join("/") + "/";
+        }
+    });
+
+    _self.__defineGetter__("name", function () {
+        return _entry.name;
+    });
+
+    _self.__defineGetter__("fullPath", function () {
+        return _r2v(_entry.fullPath);
+    });
+
+    _self.__defineGetter__("fileSize", function () {
+        if (_entry.isDirectory) {
+            return undefined;
+        } else {
+            return _entry.data.length;
+        }
+    });
+
+    _self.__defineGetter__("length", function () {
+        var _l = 0;
+        if (_entry.isDirectory) {
+            utils.forEach(_entry.children, function () {
+                _l++;
+            });
+            return _l;
+        } else {
+            return undefined;
+        }
+    });
+
+    return _self;
+};
+
+FileStream = function (entry, mode, encoding) {
+    var _entry = entry,
+        _data = entry.data,
+        _mode = mode,
+        _position = (_mode === "a" ? _data.length : 0),
+        _self;
+
+    _self = {
+        close: function () {
+            var _element;
+            if (mode === "a" || mode === "w") {
+                dbfs.write(_entry.fullPath, _data, function () {}, function () {});
+            }
+            for (_element in _self) {
+                delete _self[_element];
+            }
+        },
+        read: function (charCount) {
+            var _count  = charCount | 0,
+                _substr = _data.substring(_position, _position + _count);
+
+            if (_position + _count > _data.length) {
+                _position = _data.length;
+            } else {
+                _position += _count;
+            }
+
+            return _substr; 
+        },
+        readBytes: function (byteCount) {
+            var _substr = _self.read(byteCount),
+                _bytes = [],
+                _i;
+
+            for (_i = 0; _i < _substr.length; _i++) {
+                _bytes.push(_substr.charCodeAt(_i));
+            }
+
+            return _bytes;
+        },
+        readBase64: function (byteCount) {
+            var _substr = _self.read(byteCount);
+
+            return window.atob(_substr);
+        },
+        write: function (stringData) {
+            var _stringData = String(stringData),
+                _substr = _data.substring(0, _position);
+
+            _data = _substr.concat(_stringData);
+            _position = _data.length;
+        },
+        writeBytes: function (byteData) {
+            _self.write(String.fromCharCode.apply(String, byteData));
+        },
+        writeBase64: function (base64Data) {
+            _self.write(window.btoa(String(base64Data)));
+        }
+    };
+
+    _self.__defineGetter__("eof", function () {
+        return _position === _data.length;
+    });
+
+    _self.__defineGetter__("position", function () {
+        return _position;
+    });
+
+    _self.__defineSetter__("position", function (value) {
+        var _value = value | 0;
+
+        if (_value >= 0 && _value <= _data.length) {
+            _position = _value;
+        } else {
+            throw new DeviceApiError(errorcode.INVALID_VALUES_ERR);
+        }
+    });
+
+    _self.__defineGetter__("bytesAvailable", function () {
+        return (_data.length - _position) || -1;
+    });
+
+    return _self;
+};
+
+module.exports = function () {
+    return {
+        maxPathLength: _maxPathLength,
+        resolve: function (onSuccess, onError, srcLocation, accessMode) {
+            function _resolve() {
+                var _mode = accessMode ? String(accessMode) : _defaultMode;
+
+                if (_mode === "r" || _mode === "rw") {
+                    _resolveAsync(onSuccess, onError, String(srcLocation), _mode);
+                    return null;
+                } else {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                }
+                return undefined;
+            }
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "resolve", _resolve);
+        },
+        handleSubFeatures: function (subFeatures) {
+            if (wac2_utils.isEmptyObject(subFeatures) ||
+                subFeatures["http://wacapps.net/api/filesystem"] ||
+                (subFeatures["http://wacapps.net/api/filesystem.read"] &&
+                subFeatures["http://wacapps.net/api/filesystem.write"])) {
+                return;
+            }
+            if (subFeatures["http://wacapps.net/api/filesystem.read"]) {
+                _readOnly = true;
+                return;
+            }
+            if (subFeatures["http://wacapps.net/api/filesystem.write"]) {
+                _writeOnly = true;
+                return;
+            }
+            _console.warn("WAC-2.0-Filesystem: something wrong in handleSubFeatures");
+        }
+    }; 
+};
+
+
+});
+require.define('ripple/platform/wac/2.0/deviceapierror', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var errorcode = require('ripple/platform/wac/2.0/errorcode');
+
+module.exports = function (code) {
+    for (var c in errorcode) {
+        var g = errorcode.__lookupGetter__(c);
+        if (g) {
+            this.__defineGetter__(c, g);
+        }
+    }
+
+    this.code = code;
+    this.message = errorcode.message[code];
+    this.type =  "";
+
+    this.toString = function () {
+        var result = this.type + ': "' + this.message + '"';
+
+        if (this.stack) {
+            result += "\n" + this.stack;
+        }
+        return result;
+    };
+};
+
+
+});
+require.define('ripple/platform/wac/2.0/messagefilter', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var _self;
+
+_self = function (criteria) {
+    var pattern,
+        messageFilter;
+
+    messageFilter = {
+        match: function (target) {
+            var result = false, index;
+
+            if (Object.prototype.toString.call(criteria) === "[object Array]") {
+                for (index in criteria) {
+                    if (_self(criteria[index]).match(target))
+                        return true;
+                }
+                return false;
+            }
+
+            switch (Object.prototype.toString.call(target)) {
+            case "[object Number]":
+                result = (criteria === target);
+                break;
+
+            case "[object String]":
+                result = pattern.test(target);
+                break;
+
+            case "[object Array]":
+                for (index in target) {
+                    if (messageFilter.match(target[index]))
+                        return true;
+                }
+                break;
+            }
+
+            return result;
+        }
+    };
+
+    if (typeof criteria === "string")
+        pattern = new RegExp(criteria.replace(/(^|[^\\])%+/g, "$1.*").replace(/\\%/g, "%").replace(/.*/, "^$&$"), "i");
+
+    return messageFilter;
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/2.0/contact', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    constants = require('ripple/constants'),
+    exception = require('ripple/exception'),
+    errorcode = require('ripple/platform/wac/2.0/errorcode'),
+    wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
+    DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
+    PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
+    PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
+    TypeCoerce = require('ripple/platform/wac/2.0/typecoerce'),
+    Filter = require('ripple/platform/wac/2.0/contactfilter'),
+    AddressBook,
+    ContactProperties,
+    Contact,
+    Address,
+    ContactAddress,
+    PhoneNumber,
+    EmailAddress,
+    ContactFilter,
+    _KEY = "wac2-pim-contact",
+    _PENDING_TIME = 600,
+    _addressBooks = [],
+    _contacts = {},
+    _security = {
+        "http://wacapps.net/api/pim.contact": [],
+        "http://wacapps.net/api/pim.contact.read": ["findContacts"],
+        "http://wacapps.net/api/pim.contact.write": ["addContact", "updateContact", "deleteContact"],
+        all: true
+    },
+    _self;
+
+function _errorOccurred(onError, code) {
+    if (!onError)
+        return;
+
+    setTimeout(function () {
+        onError(new DeviceApiError(code));
+    }, 1);
+}
+
+function _pendingOperate(operate, scope) {
+    var i, argumentVector = [];
+
+    for (i = 0; i < arguments.length - 2; i++)
+        argumentVector[i] = arguments[i + 2];
+
+    return function () {
+        var pendingObj, pendingOperation;
+
+        pendingObj = new PendingObject();
+        pendingObj.pendingID = window.setTimeout(function () {
+            pendingObj.setCancelFlag(false);
+            operate.apply(scope, argumentVector);
+        }, _PENDING_TIME);
+
+        pendingOperation = new PendingOperation(pendingObj);
+
+        return pendingOperation;
+    };
+}
+
+function _defaultContacts() {
+    var id1 = Math.uuid(null, 16),
+        id2 = Math.uuid(null, 16),
+        id3 = Math.uuid(null, 16),
+        id4 = Math.uuid(null, 16),
+        contacts = {};
+
+    contacts.PHONE_ADDRESS_BOOK = {
+        type: _self().PHONE_ADDRESS_BOOK,
+        items: [{
+            id: id1,
+            firstName: "Leonardo",
+            lastName: "Gates",
+            nicknames: ["Leo"],
+            phoneticName: "",
+            addresses: [{streetAddress: "Gran Via, 32", postalCode: "50013", city: "Zaragoza", country: "ES"}],
+            photoURI: "",
+            phoneNumbers: [],
+            emails: ["leo@underground.com"]
+        }, {
+            id: id2,
+            firstName: "Jordan",
+            lastName: "",
+            nicknames: [""],
+            phoneticName: "",
+            addresses: [],
+            photoURI: "",
+            phoneNumbers: [],
+            emails: ["jordan@underground.com"]
+        }]
+    };
+
+    contacts.SIM_ADDRESS_BOOK = {
+        type: _self().SIM_ADDRESS_BOOK,
+        items: [{
+            id: id3,
+            firstName: "Raphael",
+            lastName: "",
+            nicknames: [""],
+            phoneticName: "",
+            addresses: [],
+            photoURI: "",
+            phoneNumbers: [],
+            emails: ["raph@underground.com"]
+        }]
+    };
+
+    contacts.DEVICE_ADDRESS_BOOK = {
+        type: _self().DEVICE_ADDRESS_BOOK,
+        items: [{
+            id: id4,
+            firstName: "Michelangelo",
+            lastName: "",
+            nicknames: [""],
+            phoneticName: "",
+            addresses: [],
+            photoURI: "",
+            phoneNumbers: [],
+            emails: ["mike@underground.com"]
+        }]
+    };
+
+    return contacts;
+}
+
+function _get() {
+    _contacts = db.retrieveObject(_KEY) || _defaultContacts();
+}
+
+function _save() {
+    db.saveObject(_KEY, _contacts);
+}
+
+function _initAddressBooks() {
+    _get();
+    utils.forEach(_contacts, function (contactObj, name) {
+        _addressBooks.push(new AddressBook(contactObj.type, name));
+    });
+}
+
+_self = function () {
+    var contact = {
+        getAddressBooks: function (successCallback, errorCallback) {
+            function _getAddressBooks() {
+                if (_addressBooks.length === 0) {
+                    _initAddressBooks();
+                }
+                successCallback(_addressBooks);
+            }
+            return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "getAddressBooks", _getAddressBooks);
+        },
+
+        handleSubFeatures: function (subFeatures) {
+            for (var subFeature in subFeatures) {
+                if (_security[subFeature].length === 0) {
+                    _security.all = true;
+                    return;
+                }
+                _security.all = false;
+                utils.forEach(_security[subFeature], function (method) {
+                    _security[method] = true;
+                });
+            }
+        }
+    };
+
+    contact.__defineGetter__("SIM_ADDRESS_BOOK", function () {
+        return 0x0000;
+    });
+
+    contact.__defineGetter__("DEVICE_ADDRESS_BOOK", function () {
+        return 0x000F;
+    });
+
+    contact.__defineGetter__("PHONE_ADDRESS_BOOK", function () {
+        return 0x00FF;
+    });
+
+    return contact;
+};
+
+AddressBook = function (type, name) {
+    var addressBook,
+        contactItems = _contacts[name].items;
+
+    addressBook = {
+        createContact: function (contactProperties) {
+            var cp, contact = new Contact();
+
+            if ((contactProperties !== undefined) &&
+                (contactProperties !== null)) {
+                cp = TypeCoerce(ContactProperties).cast(contactProperties);
+                !cp.firstName    || (contact.firstName    = utils.copy(cp.firstName));
+                !cp.lastName     || (contact.lastName     = utils.copy(cp.lastName));
+                !cp.nicknames    || (contact.nicknames    = utils.copy(cp.nicknames));
+                !cp.phoneticName || (contact.phoneticName = utils.copy(cp.phoneticName));
+                !cp.addresses    || (contact.addresses    = utils.copy(cp.addresses));
+                !cp.photoURI     || (contact.photoURI     = utils.copy(cp.photoURI));
+                !cp.phoneNumbers || (contact.phoneNumbers = utils.copy(cp.phoneNumbers));
+                !cp.emails       || (contact.emails       = utils.copy(cp.emails));
+            }
+
+            return contact;
+        },
+
+        addContact: function (successCallback, errorCallback, contact) {
+            function _addContact() {
+                var c;
+
+                if (!contact)
+                    exception.raise(exception.types.Argument, "addContact invalid message parameter", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+
+                if (!_security.all && !_security.addContact)
+                    return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
+
+                c = TypeCoerce(new Contact()).cast(contact);
+                contactItems.push(c);
+                _save();
+                successCallback(c);
+            }
+            return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "addContact", _pendingOperate(_addContact));
+        },
+
+        updateContact: function (successCallback, errorCallback, contact) {
+            function _updateContact() {
+                var c, isFound = false;
+
+                if (!contact)
+                    exception.raise(exception.types.Argument, "updateContact invalid message parameter", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+
+                if (!_security.all && !_security.updateContact)
+                    return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
+
+                c = TypeCoerce(new Contact()).cast(contact);
+                utils.forEach(contactItems, function (contactItem) {
+                    if (contactItem.id === c.id) {
+                        !c.firstName    || (contactItem.firstName    = utils.copy(c.firstName));
+                        !c.lastName     || (contactItem.lastName     = utils.copy(c.lastName));
+                        !c.nicknames    || (contactItem.nicknames    = utils.copy(c.nicknames));
+                        !c.phoneticName || (contactItem.phoneticName = utils.copy(c.phoneticName));
+                        !c.addresses    || (contactItem.addresses    = utils.copy(c.addresses));
+                        !c.photoURI     || (contactItem.photoURI     = utils.copy(c.photoURI));
+                        !c.phoneNumbers || (contactItem.phoneNumbers = utils.copy(c.phoneNumbers));
+                        !c.emails       || (contactItem.emails       = utils.copy(c.emails));
+
+                        _save();
+                        isFound = true;
+                        successCallback();
+                    }
+                });
+
+                if (!isFound)
+                    _errorOccurred(errorCallback, errorcode.NOT_FOUND_ERR);
+            }
+            return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "updateContact", _pendingOperate(_updateContact));
+        },
+
+        deleteContact: function (successCallback, errorCallback, id) {
+            function _deleteContact() {
+                var isFound = false;
+
+                if (!_security.all && !_security.deleteContact)
+                    return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
+
+                utils.forEach(contactItems, function (contactItem, index) {
+                    if (contactItem.id === id) {
+                        contactItems.splice(index, 1);
+                        _save();
+                        isFound = true;
+                        successCallback();
+                    }
+                });
+
+                if (!isFound)
+                    _errorOccurred(errorCallback, errorcode.NOT_FOUND_ERR);
+            }
+            return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "deleteContact", _pendingOperate(_deleteContact));
+        },
+
+        findContacts: function (successCallback, errorCallback, filter) {
+            function _findContacts() {
+                var contact, result = [];
+
+                if (!_security.all && !_security.findContacts)
+                    return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
+
+                utils.forEach(contactItems, function (contactItem) {
+                    if ((filter              === undefined || filter === null) ||
+                        (filter.id           === undefined || Filter(filter.id).match(contactItem.id)) &&
+                        (filter.firstName    === undefined || Filter(filter.firstName).match(contactItem.firstName)) &&
+                        (filter.lastName     === undefined || Filter(filter.lastName).match(contactItem.lastName)) &&
+                        (filter.phoneticName === undefined || Filter(filter.phoneticName).match(contactItem.phoneticName)) &&
+                        (filter.nickname     === undefined || Filter(filter.nickname).match(contactItem.nicknames)) &&
+                        (filter.phoneNumber  === undefined || Filter(filter.phoneNumber).match(contactItem.phoneNumbers)) &&
+                        (filter.email        === undefined || Filter(filter.email).match(contactItem.emails)) &&
+                        (filter.address      === undefined || Filter(filter.address).match(contactItem.addresses))) {
+                        contact = new Contact(contactItem.id);
+
+                        contact.firstName    = utils.copy(contactItem.firstName);
+                        contact.lastName     = utils.copy(contactItem.lastName);
+                        contact.nicknames    = utils.copy(contactItem.nicknames);
+                        contact.phoneticName = utils.copy(contactItem.phoneticName);
+                        contact.addresses    = utils.copy(contactItem.addresses);
+                        contact.photoURI     = utils.copy(contactItem.photoURI);
+                        contact.phoneNumbers = utils.copy(contactItem.phoneNumbers);
+                        contact.emails       = utils.copy(contactItem.emails);
+
+                        result.push(contact);
+                    }
+                });
+                successCallback(result);
+            }
+            return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "findContacts", _pendingOperate(_findContacts));
+        }
+    };
+
+    addressBook.__defineGetter__("type", function () {
+        return type;
+    });
+
+    addressBook.__defineGetter__("name", function () {
+        return name;
+    });
+
+    return addressBook;
+};
+
+Address = {
+    country: "",
+    region: "",
+    county: "",
+    city: "",
+    streetAddress: "",
+    additionalInformation: "",
+    postalCode: ""
+};
+
+ContactAddress = function () {
+    this.types = [""]; // "WORK", "PREF", "HOME"
+};
+
+ContactAddress.prototype = Address;
+
+PhoneNumber = {
+    number: "",
+    types: [""] // "WORK", "PREF", "HOME", "VOICE", "FAX", "MSG", "CELL",
+                // "PAGER", "BBS", "MODEM", "CAR", "ISDN", "VIDEO", "PCS"
+};
+
+EmailAddress = {
+    email: "",
+    types: [""] // "WORK", "PREF", "HOME"
+};
+
+ContactProperties = {
+    firstName: "",
+    lastName: "",
+    nicknames: [""],
+    phoneticName: "",
+    addresses: [new ContactAddress()],
+    photoURI: "",
+    phoneNumbers: [PhoneNumber],
+    emails: [EmailAddress]
+};
+
+Contact = function (id) {
+    id = id || Math.uuid(null, 16);
+
+    this.__defineGetter__("id", function () {
+        return id;
+    });
+};
+
+Contact.prototype = ContactProperties;
+
+ContactFilter = {
+    id: "",
+    firstName: "",
+    lastName: "",
+    phoneticName: "",
+    nickname: "",
+    phoneNumber: "",
+    email: "",
+    address: ""
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/2.0/typecoerce', function (require, module, exports) {
+/*\r
+ *  Copyright 2011 Intel Corporation.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+var utils = require('ripple/utils'),\r
+    _self;\r
+\r
+_self = function (pattern) {\r
+    var typeCoerce,\r
+        typeOfPattern = Object.prototype.toString.call(pattern);\r
+\r
+    typeCoerce = {\r
+        cast: function (obj) {\r
+            var validObj,\r
+                validValue,\r
+                elementType,\r
+                typeOfObj = Object.prototype.toString.call(obj);\r
+\r
+            switch (typeOfPattern) {\r
+            case "[object String]":\r
+                validObj = (typeOfObj !== typeOfPattern) ? String(obj) : obj;\r
+                break;\r
+\r
+            case "[object Number]":\r
+                validObj = (typeOfObj !== typeOfPattern) ? (Number(obj) | 0) : obj;\r
+                break;\r
+\r
+            case "[object Object]":\r
+                if (typeOfObj !== typeOfPattern) {\r
+                    validObj = {};\r
+                } else {\r
+                    validObj = obj;\r
+                    utils.forEach(validObj, function (value, key) {\r
+                        if (pattern[key] === undefined) {\r
+                            delete validObj[key];\r
+                        } else {\r
+                            validValue = _self(pattern[key]).cast(value);\r
+                            if (validObj[key] !== validValue)\r
+                                validObj[key] = validValue;\r
+                        }\r
+                    });\r
+                }\r
+                break;\r
+\r
+            case "[object Array]":\r
+                if (typeOfObj !== typeOfPattern) {\r
+                    validObj = [];\r
+                } else {\r
+                    validObj = obj;\r
+                    elementType = _self(pattern[0]);\r
+                    utils.forEach(validObj, function (element, index) {\r
+                        validObj[index] = elementType.cast(element);\r
+                    });\r
+                }\r
+                break;\r
+            }\r
+\r
+            return validObj;\r
+        }\r
+    };\r
+\r
+    return typeCoerce;\r
+};\r
+\r
+module.exports = _self;\r
+
+});
+require.define('ripple/platform/wac/2.0/camera', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    constants = require('ripple/constants'),
+    _console = require('ripple/console'),
+    errorcode = require('ripple/platform/wac/2.0/errorcode'),
+    PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
+    PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
+    DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
+    wac2_utils = require('ripple/platform/wac/2.0/wac2_utils');
+
+module.exports = function () {
+    var _cameraArray, Camera, _videoStatus = {},
+        _captureImage, _startVideoCapture,
+        _doCaptureImage, _doStartVideoCapture,
+        _doGetPreview, _doGetCameras,
+        _stopVideoCapture, _createPreviewNode,
+        _FAKEWAITTIME = 5,
+        _defaultHighRes = true,
+        _defaultImageFilename = "_capture.jpg",
+        _defaultVideoFilename = "_capture.avi",
+        _captureImageAllowed = true,
+        _startVideoCaptureAllowed = true,
+        _stopVideoCaptureAllowed = true,
+        _createPreviewNodeAllowed = true;
+
+    _doCaptureImage = function (onSuccess, onError, capFilename, capHighRes, pendingObj) {
+        pendingObj.pendingID = setTimeout(function () {
+            var dname = "", fname = "";
+            //pretend to do sth.
+            pendingObj.setCancelFlag(false);  // too late to cancel
+            if (capFilename.indexOf("/") !== -1) {
+                dname = capFilename.replace(/(.*\/)[^\/]+$/i, "$1");
+                fname = capFilename.replace(/.*\/([^\/]*)$/i, "$1");
+                //replace extension with jpg
+                fname = fname.replace(/\.[^\/\.]+$/i, ".jpg");
+            } else {
+                dname = "";
+                fname = capFilename.replace(/\.[^\/\.]+$/i, ".jpg");
+            }
+            if (fname === "") {
+                fname = _defaultImageFilename;
+            }
+            if (fname.search(/\.jpg$/) === -1) {
+                fname = fname + ".jpg";
+            }
+            if (capHighRes) {
+                onSuccess(dname + "high-" + fname);
+            } else {
+                onSuccess(dname + "low-" + fname);
+            }
+        }, _FAKEWAITTIME);
+    };
+
+    _captureImage = function (onSuccess, onError, options) {
+        var pendingOperation = {}, pendingObj,
+            filename = this.id + _defaultImageFilename,
+            highRes = _defaultHighRes, opt;
+
+        if (onSuccess) {
+            utils.validateArgumentType(onSuccess, "function", null, "captureImage: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (onError) {
+            utils.validateArgumentType(onError, "function", null, "captureImage: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (options) {
+            opt = new Object(options);
+            /* NOTE: if desktinationFilename or highRes is not provided by
+               user, i.e. undefined or null, a default value is used.
+             */
+            if (opt.destinationFilename !== null && opt.destinationFilename !== undefined) {
+            // TODO: validate filename via Filesystem.resolve()
+                filename = String(opt.destinationFilename);
+            }
+            if (opt.highRes !== null && opt.highRes !== undefined) {
+                highRes = Boolean(opt.highRes);
+            }
+        }
+        if (!_captureImageAllowed) {
+            if (onError) {
+                setTimeout(function () {
+                    onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                }, 1);
+            }
+            return undefined;
+        }
+
+        if (onSuccess) {
+            pendingObj = new PendingObject();
+            _doCaptureImage(onSuccess, onError, filename, highRes, pendingObj);
+            pendingOperation = new PendingOperation(pendingObj);
+            return pendingOperation;
+        } else {
+            if (onError) {
+                setTimeout(function () {
+                    onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                }, 1);
+            }
+        }
+        return undefined;
+    };
+
+    _stopVideoCapture = function () {
+        var dname = "", fname = "", capFilename = _videoStatus[this.id].capFilename;
+        if (_videoStatus[this.id]) {
+            if (capFilename.indexOf("/") !== -1) {
+                dname = capFilename.replace(/(.*\/)[^\/]+$/i, "$1");
+                fname = capFilename.replace(/.*\/([^\/]*)$/i, "$1");
+                //replace extension with avi
+                fname = fname.replace(/\.[^\/\.]+$/i, ".avi");
+            } else {
+                dname = "";
+                fname = capFilename.replace(/\.[^\/\.]+$/i, ".avi");
+            }
+            if (fname === "") {
+                fname = _defaultVideoFilename;
+            }
+            if (fname.search(/\.avi$/) === -1) {
+                fname = fname + ".avi";
+            }
+            if (_videoStatus[this.id].capHighRes) {
+                _videoStatus[this.id].capSuccess(dname + "high-" + fname);
+            } else {
+                _videoStatus[this.id].capSuccess(dname + "low-" + fname);
+            }
+            delete _videoStatus[this.id];
+        }
+    };
+
+    _doStartVideoCapture = function (camID, onSuccess, onError, filename, highRes, pendingObj) {
+        var videoStatus = {};
+        _videoStatus[camID] = videoStatus;
+        pendingObj.userCancel = function () {
+            delete _videoStatus[camID];
+        };
+        pendingObj.getCancelFlag = function () {
+            return !!_videoStatus[camID];
+        };
+        pendingObj.pendingID = setTimeout(function () {
+            // waiting to be cancelled
+            videoStatus = {
+                capSuccess: onSuccess,
+                capError: onError,
+                capFilename: filename,
+                capHighRes: highRes
+            };
+            _videoStatus[camID] = videoStatus;
+        }, _FAKEWAITTIME);
+    };
+
+    _startVideoCapture = function (onSuccess, onError, options) {
+        var pendingOperation = {}, pendingObj,
+            filename = this.id + _defaultVideoFilename,
+            highRes = _defaultHighRes, opt;
+
+        if (onSuccess) {
+            utils.validateArgumentType(onSuccess, "function", null, "startVideoCapture: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (onError) {
+            utils.validateArgumentType(onError, "function", null, "startVideoCapture: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (options) {
+            opt = new Object(options);
+            /* NOTE: if desktinationFilename or highRes is not provided by
+               user, i.e. undefined or null, a default value is used.
+             */
+            if (opt.destinationFilename !== null && opt.destinationFilename !== undefined) {
+            // TODO: validate filename via Filesystem.resolve()
+                filename = String(opt.destinationFilename);
+            }
+            if (opt.highRes !== null && opt.highRes !== undefined) {
+                highRes = Boolean(opt.highRes);
+            }
+        }
+        if (!_captureImageAllowed) {
+            if (onError) {
+                setTimeout(function () {
+                    onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                }, 1);
+            }
+            return undefined;
+        }
+        if (_videoStatus[this.id]) { 
+            // capture already started
+            _console.warn("WAC-2.0-startVideoCapture: capture already started");
+            if (onError) {
+                setTimeout(function () {
+                    onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
+                }, 1);
+            }
+            return undefined;
+        }
+
+        if (onSuccess) {
+            pendingObj = new PendingObject();
+            _doStartVideoCapture(this.id, onSuccess, onError, filename, highRes, pendingObj);
+            
+            pendingOperation = new PendingOperation(pendingObj);
+            return pendingOperation;
+        } else {
+            if (onError) {
+                setTimeout(function () {
+                    onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                }, 1);
+            }
+        }
+        return undefined;
+    };
+
+    _doGetPreview = function (camID, onSuccess, onError, pendingObj) {
+        var container, demoImg, loc, imageSrc;
+        container = document.createElement("div");
+        container.setAttribute("id", camID + "-wac-2-0-camera-preview-container");
+        demoImg = document.createElement("img");
+        demoImg.setAttribute("id", camID + "-wac-2-0-camera-demo-image");
+        loc = document.location;
+        imageSrc = loc.protocol + "//" + loc.hostname + loc.pathname.replace(/index\.html$/, "") + constants.CAMERA.WINDOW_ANIMATION;
+        demoImg.setAttribute("src", imageSrc);
+        demoImg.setAttribute("width", "100%");
+        container.appendChild(demoImg);
+        
+        pendingObj.pendingID = setTimeout(function () {
+            pendingObj.setCancelFlag(false);  // too late to cancel
+            onSuccess(container);
+        }, _FAKEWAITTIME);
+    };
+
+    _createPreviewNode = function (onSuccess, onError) {
+        var pendingOperation, pendingObj = {};
+        if (onSuccess) {
+            utils.validateArgumentType(onSuccess, "function", null, "createPreviewNode: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (onError) {
+            utils.validateArgumentType(onError, "function", null, "createPreviewNode: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (!_createPreviewNodeAllowed) {
+            if (onError) {
+                setTimeout(function () {
+                    onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                }, 1);
+            }
+            return undefined;
+        }
+        if (onSuccess) {
+            pendingObj = new PendingObject();
+            _doGetPreview(this.id, onSuccess, onError, pendingObj);
+            pendingOperation = new PendingOperation(pendingObj);
+            return pendingOperation;
+        } else {
+            if (onError) {
+                setTimeout(function () {
+                    onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                }, 1);
+            }
+        }
+        return undefined;
+    };
+
+    Camera = function (cameraID) {
+        return {
+            id: cameraID,
+            captureImage: _captureImage,
+            startVideoCapture: _startVideoCapture,
+            stopVideoCapture: _stopVideoCapture,
+            createPreviewNode: _createPreviewNode
+        };
+    };
+
+    _cameraArray = [new Camera("rear"), new Camera("front")];
+
+    _doGetCameras = function (onSuccess, onError, pendingObj) {
+        pendingObj.pendingID = setTimeout(function () {
+            pendingObj.setCancelFlag(false);  // too late to cancel
+            if (_cameraArray.length !== 0) {
+                onSuccess(utils.copy(_cameraArray));
+            } else {
+                // no camera
+                if (onError) {
+                    setTimeout(function () {
+                        onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
+                    }, 1);
+                }
+            }
+        }, _FAKEWAITTIME);
+    };
+
+    this.getCameras = function (onSuccess, onError) {
+        var pendingOperation, pendingObj = {};
+        if (onSuccess) {
+            utils.validateArgumentType(onSuccess, "function", null, "getCameras: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (onError) {
+            utils.validateArgumentType(onError, "function", null, "getCameras: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+        }
+        if (onSuccess) {
+            pendingObj = new PendingObject();
+            _doGetCameras(onSuccess, onError, pendingObj);
+            pendingOperation = new PendingOperation(pendingObj);
+            return pendingOperation;
+        } else {
+            if (onError) {
+                setTimeout(function () {
+                    onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                }, 1);
+            }
+        }
+        return undefined;
+    };
+
+    this.handleSubFeatures = function (subFeatures) {
+        if (wac2_utils.isEmptyObject(subFeatures) ||
+            subFeatures["http://wacapps.net/api/camera"] ||
+            (subFeatures["http://wacapps.net/api/camera.capture"] &&
+            subFeatures["http://wacapps.net/api/camera.show"])) {
+            return;
+        }
+        if (subFeatures["http://wacapps.net/api/camera.show"] &&
+           !subFeatures["http://wacapps.net/api/camera.capture"]) {
+            _captureImageAllowed = false;
+            _startVideoCaptureAllowed = false;
+            _stopVideoCaptureAllowed = false;
+            return;
+        }
+        if (subFeatures["http://wacapps.net/api/camera.capture"] &&
+           !subFeatures["http://wacapps.net/api/camera.show"]) {
+            _createPreviewNodeAllowed = false;
+            return;
+        }
+        _console.warn("WAC-2.0-Camera-handleSubFeatures: something wrong");
+    };
+};
+
+});
+require.define('ripple/platform/wac/2.0/deviceapis', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var platform = require('ripple/platform'),
+    app = require('ripple/app'),
+    utils = require('ripple/utils'),
+    init_done = false,
+    _activatedSet = {},
+    _activatedFeatures = [],
+    _availableSet = {},
+    _availableFeatures = [],
+    _features = {},
+    initFeaturesSet,
+    populateFeatures;
+
+populateFeatures = function (objects) {
+    utils.forEach(objects, function (obj, key) {
+        var objFeatures = {}, rpt, i, j;
+        if (obj.feature) {
+            objFeatures = obj.feature.split('|');
+            utils.forEach(objFeatures, function (feature) {
+                var avail = {uri: feature,
+                             required: false,
+                             param: null};
+                _availableSet[feature] = avail;
+            });
+            if (_features) {
+                rpt = objFeatures.length;
+                j = 0;
+                for (i = 0; i < rpt; i++) {
+                    if (!_features[objFeatures[j]]) {
+                        objFeatures.splice(j, 1);
+                    } else {
+                        j++;
+                    }
+                }
+            }
+            utils.forEach(objFeatures, function (feature) {
+                var avail = {uri: feature,
+                             required: true,
+                             param: null};
+                _activatedSet[feature] = avail;
+            });
+        }
+        if (obj.children) {
+            populateFeatures(obj.children);
+        }
+    });
+};
+
+initFeaturesSet = function () {
+    _features = utils.copy(app.getInfo().features);
+    populateFeatures(platform.current().objects);
+    utils.forEach(_activatedSet, function (obj, key) {
+            _activatedFeatures.push(obj);
+        });
+    utils.forEach(_availableSet, function (obj, key) {
+            _availableFeatures.push(obj);
+        });
+    init_done = true;
+};
+
+module.exports = {
+    listAvailableFeatures: function () {
+        if (!init_done)
+            initFeaturesSet();
+        return _availableFeatures;
+    },
+
+    listActivatedFeatures: function () {
+        if (!init_done)
+            initFeaturesSet();
+        return _activatedFeatures;
+    }
+};
+
+
+});
+require.define('ripple/platform/wac/2.0/pendingObject', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (pendingObj) {
+    var cancelFlag = true;
+    this.setCancelFlag = function (flag) {
+        cancelFlag = flag;
+    };
+    this.getCancelFlag = function () {
+        return cancelFlag;
+    };
+    this.userCancel = null;
+    this.pendingID = null;
+};
+
+});
+require.define('ripple/platform/wac/2.0/devicestatus', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
+    errorcode = require('ripple/platform/wac/2.0/errorcode'),
+    _console = require('ripple/console'),
+    DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
+    deviceSettings = require('ripple/deviceSettings'),    
+    event = require('ripple/event'),    
+    PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
+    PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
+    _getDeviceInfoAspect = true,
+    _getNetworkInfoAspect = true,    
+    _deviceInfoAspect = ["Battery", "Device", "Display", "MemoryUnit", "OperatingSystem", "WebRuntime"],    
+    _networkInfoAspect = ["CellularHardware", "CellularNetwork", "WiFiHardware", "WiFiNetwork"],
+    _aspectArray = [], 
+    _propertyMap = {},
+    _watches = {},
+    _self;
+
+function _asynchErrorCallback(errorCallback, errorCode) {
+    if (errorCallback) {        
+        setTimeout(function () {
+            errorCallback(errorCode);
+        }, 1);  
+    }
+}
+
+function _initialize() {
+    var aspectName, index, i;
+
+    _aspectArray = _deviceInfoAspect.concat(_networkInfoAspect);
+    for (index = 0; index < _aspectArray.length; index++) {
+        aspectName = _aspectArray[index];
+        _propertyMap[aspectName] = [];
+        for (i in deviceSettings.retrieve(aspectName)) {
+            _propertyMap[aspectName].push(i);
+        }
+    }     
+}
+
+function _isPropertyFound(aspect, property) {
+    if (_aspectArray.length === 0) {
+        _initialize();
+    }
+
+    if (_propertyMap[aspect]) {
+        if (property) {
+            return _propertyMap[aspect].some(function (prop) {
+                return prop === property;
+            });
+        }
+        return true;
+    }
+    return false;
+}
+
+function _isPropertyAllowed(aspect) {
+    function hasAspect(asp) {
+        return asp === aspect;
+    }
+
+    if ((_deviceInfoAspect.some(hasAspect) && _getDeviceInfoAspect === false) ||
+        (_networkInfoAspect.some(hasAspect) && _getNetworkInfoAspect === false)) {
+        return false;
+    }
+
+    return true;
+}
+
+function _isPropertyValid(prop, errorCallback) {
+    var _prop = Object(prop);
+
+    if (_prop && _prop.aspect && _prop.property) {
+        if (_isPropertyFound(_prop.aspect, _prop.property) === false) {
+            _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.NOT_FOUND_ERR));
+            return false;
+        }
+        else if (_isPropertyAllowed(_prop.aspect) === false) {
+            _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.SECURITY_ERR));
+            return false;
+        }
+    } 
+    else {
+        _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+        return false;
+    }
+    return true;
+}
+
+module.exports = function () {
+    return {  
+        getComponents: function (aspect) {
+            if (_isPropertyFound(aspect))
+                return ["_default"];
+            return null;              
+        },
+
+        isSupported: function (aspect, property) {
+            return _isPropertyFound(aspect, property);
+        },
+
+        getPropertyValue: function (successCallback, errorCallback, prop) {
+            return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "getPropertyValue", function () {                                  
+                if (_isPropertyValid(prop, errorCallback) !== true)
+                    return undefined;
+                
+                var value = deviceSettings.retrieve(prop.aspect + "." + prop.property);
+                if (value !== undefined) {
+                    successCallback(value, prop);
+                }
+                else {
+                    _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.NOT_AVAILABLE_ERR)); 
+                }
+                
+                return null;    
+            });        
+        },
+       
+        watchPropertyChange: function (successCallback, errorCallback, prop, options) {  
+            return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "watchPropertyChange", function () {
+                if (_isPropertyValid(prop, errorCallback) !== true)
+                    return undefined;
+
+                var _options = Object(options),
+                    eventType = deviceSettings.retrieve(prop.aspect)[prop.property].event,
+                    watchObj = {
+                        eventType: eventType,
+                        onEvent: function (newValue) {
+                            if (watchObj.timeStamp && 
+                                ((new Date()).getTime() - watchObj.timeStamp < options.minNotificationInterval)) {
+                                return undefined;
+                            }                       
+                            else if (watchObj.value &&
+                                     (newValue > watchObj.value * (1 - _options.minChangePercent) && 
+                                      newValue < watchObj.value * (1 + _options.minChangePercent))) {
+                                return undefined;
+                            }
+
+                            if (watchObj.intervalId) {
+                                clearInterval(watchObj.intervalId);
+                                watchObj.intervalId = setInterval(function () {
+                                    successCallback(deviceSettings.retrieve(prop.aspect + "." + prop.property), prop);
+                                }, _options.maxNotificationInterval);
+                            }
+                            successCallback(newValue, prop);
+                            if (watchObj.timeStamp) {
+                                watchObj.timeStamp = (new Date()).getTime();
+                            }
+                            if (watchObj.value) {
+                                watchObj.value = newValue;
+                            }
+                        }                              
+                    },
+                    watchId = (new Date()).getTime() | 0;
+
+                if (options && _options.minNotificationInterval && _options.maxNotificationInterval && 
+                    (_options.minNotificationInterval < 0 || _options.maxNotificationInterval < 0 || 
+                     _options.minNotificationInterval >= _options.maxNotificationInterval)) {
+                    _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                    return undefined;
+                }
+
+                if (options && _options.maxNotificationInterval) {
+                    watchObj.intervalId = setInterval(function () {
+                        successCallback(deviceSettings.retrieve(prop.aspect + "." + prop.property), prop);
+                    }, _options.maxNotificationInterval);
+                }    
+
+                if (options && _options.minNotificationInterval) {
+                    watchObj.timeStamp = (new Date()).getTime();
+                }                    
+
+                if (options && _options.minChangePercent) {
+                    if (_options.minNotificationInterval || _options.maxNotificationInterval) {}
+                    else {                
+                        watchObj.value = deviceSettings.retrieve(prop.aspect + "." + prop.property);
+                    }
+                }
+               
+                _watches[watchId] = watchObj;
+                if (watchObj.eventType) {
+                    event.on(watchObj.eventType, watchObj.onEvent);
+                }
+
+                return watchId;
+            });             
+        },
+
+        clearPropertyChange: function (watchHandler) {
+            var _handler = watchHandler | 0;
+            
+            if (_watches[_handler]) {
+                event.deleteEventHandler(_watches[_handler].eventType, _watches[_handler].onEvent);            
+                if (_watches[_handler].intervalId) {
+                    clearInterval(_watches[_handler].intervalId);
+                }
+                delete(_watches[_handler]); 
+            }
+            return null;
+        },
+
+        handleSubFeatures: function (subFeatures) {
+            if (wac2_utils.isEmptyObject(subFeatures) ||
+                subFeatures["http://wacapps.net/api/devicestatus"] || 
+                (subFeatures["http://wacapps.net/api/devicestatus.deviceinfo"] &&
+                 subFeatures["http://wacapps.net/api/devicestatus.networkinfo"])) {
+                return;
+            }
+            if (subFeatures["http://wacapps.net/api/devicestatus.deviceinfo"]) {
+                _getNetworkInfoAspect = false;
+                return;
+            }
+            if (subFeatures["http://wacapps.net/api/devicestatus.networkinfo"]) {
+                _getDeviceInfoAspect = false;
+                return;
+            }
+            _console.warn("WAC-2.0-Devicestatus-handleSubFeatures: something wrong");
+        }
+    };
+};
+
+
+});
+require.define('ripple/platform/wac/2.0/messaging', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    db = require('ripple/db'),
+    exception = require('ripple/exception'),
+    errorcode = require('ripple/platform/wac/2.0/errorcode'),
+    wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
+    DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
+    PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
+    PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
+    TypeCoerce = require('ripple/platform/wac/2.0/typecoerce'),
+    Filter = require('ripple/platform/wac/2.0/messagefilter'),
+    FileSystem = require('ripple/platform/wac/2.0/filesystem'),
+    MessageSendCallback,
+    Message,
+    MessageFilter,
+    Recipients,
+    _KEY = "wac2-pim-messaging",
+    _PENDING_TIME = 600,
+    _messages = {},
+    _subscriber = {
+        onSMS: {},
+        onMMS: {},
+        onEmail: {}
+    },
+    _sentStatus = {},
+    _security = {
+        "http://wacapps.net/api/messaging": [],
+        "http://wacapps.net/api/messaging.send": ["sendMessage"],
+        "http://wacapps.net/api/messaging.find": ["findMessages"],
+        "http://wacapps.net/api/messaging.subscribe": ["onSMS", "onMMS", "onEmail"],
+        "http://wacapps.net/api/messaging.write": ["update"],
+        all: true
+    },
+    _fileSystem,
+    _initialized = false,
+    _self;
+
+function _initialize() {
+    _get();
+    if (!_fileSystem) {
+        _fileSystem = new FileSystem();
+    }
+    _initialized = true;
+}
+
+function _get() {
+    _messages = db.retrieveObject(_KEY) || {1: [], 2: [], 3: [], 4: []};
+    utils.forEach(_messages, function (folder) {
+        utils.forEach(folder, function (messageItem) {
+            if (messageItem.timestamp)
+                messageItem.timestamp = new Date(messageItem.timestamp);
+        });
+    });
+}
+
+function _save() {
+    db.saveObject(_KEY, _messages);
+}
+
+function _updateDB(message, duplicate) {
+    _get();
+    _messages[message.folder].push(message);
+    if (duplicate)
+        _messages[duplicate.folder].push(duplicate);
+    _save();
+}
+
+function _processAttachments(message) {
+    var attachmentsFileName = [],
+        attachmentsContent = [];
+
+    function _generateAttachmentFileName(attachment) {
+        var lastDot = attachment.filename.lastIndexOf(".");
+        return attachment.filename.substring(0, lastDot) + "_" + Math.uuid(8, 16) + attachment.filename.substring(lastDot);
+    }
+
+    function _onResolveSuccess(file) {
+        var fileAttachment = file.createFile(attachmentsFileName[0]);
+
+        fileAttachment.openStream(
+            function (fs) {
+                fs.write(attachmentsContent[0]);
+                fs.close();
+            }, null, "w");
+    }
+
+    function _onResolveError() {
+    }
+
+    if (message.attachments.length === 0)
+        return;
+
+    attachmentsFileName.push(_generateAttachmentFileName(message.attachments[0]));
+    attachmentsContent.push(message.attachments[0].content);
+
+    _fileSystem.resolve(_onResolveSuccess, _onResolveError, "attachments", "rw");
+
+    message.attachments = utils.copy(attachmentsFileName);
+}
+
+function _errorOccurred(onError, code) {
+    if (!onError)
+        return;
+
+    setTimeout(function () {
+        onError(new DeviceApiError(code));
+    }, 1);
+}
+
+function _pendingOperate(operate, scope) {
+    var i, argumentVector = [];
+
+    for (i = 0; i < arguments.length - 2; i++)
+        argumentVector[i] = arguments[i + 2];
+
+    return function () {
+        var pendingObj, pendingOperation;
+
+        pendingObj = new PendingObject();
+        pendingObj.pendingID = window.setTimeout(function () {
+            pendingObj.setCancelFlag(false);
+            if (operate)
+                operate.apply(scope, argumentVector);
+        }, _PENDING_TIME);
+
+        pendingOperation = new PendingOperation(pendingObj);
+
+        return pendingOperation;
+    };
+}
+
+function _onMessage(onMessage, messageHandler) {
+    if (!messageHandler)
+        exception.raise(exception.types.Argument,
+            onMessage + " invalid messageHandler parameter",
+            new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+
+    utils.validateArgumentType(messageHandler, "function", null,
+        "messageHandler invalid function parameter",
+        new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+
+    if (!_security.all && !_security[onMessage])
+        exception.raise(exception.types.Argument,
+            onMessage + " access denied", new DeviceApiError(errorcode.SECURITY_ERR));
+
+    var idSubscribe = (new Date()).getTime() | 0;
+    _subscriber[onMessage][idSubscribe] = messageHandler;
+
+    return idSubscribe;
+}
+
+function _validateRecipients(message) {
+    var i;
+
+    for (i = 0; i < message.to.length;) {
+        message.to[i] = message.to[i].replace(/^\s*(\S*)\s*$/, '$1');
+        if (message.to[i] === "")
+            message.to.splice(i, 1);
+        else
+            i++;
+    }
+    for (i = 0; i < message.cc.length;) {
+        message.cc[i] = message.cc[i].replace(/^\s*(\S*)\s*$/, '$1');
+        if (message.cc[i] === "")
+            message.cc.splice(i, 1);
+        else
+            i++;
+    }
+    for (i = 0; i < message.bcc.length;) {
+        message.bcc[i] = message.bcc[i].replace(/^\s*(\S*)\s*$/, '$1');
+        if (message.bcc[i] === "")
+            message.bcc.splice(i, 1);
+        else
+            i++;
+    }
+    if (message.to.length + message.cc.length + message.bcc.length === 0)
+        exception.raise(exception.types.Argument,
+            "sendMessage invalid message.to parameter",
+            new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+}
+
+function _isValid(onSuccess, onError, message) {
+    if (onSuccess &&
+        typeof onSuccess !== "function" &&
+        typeof onSuccess !== "object") {
+        exception.raise(exception.types.Argument,
+            "sendMessage invalid successCallback parameter",
+            new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+    }
+
+    if (onError) {
+        utils.validateArgumentType(onError, "function", null,
+            "sendMessage invalid errorCallback parameter",
+            new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+    }
+
+    if (!onSuccess) {
+        _errorOccurred(onError, errorcode.INVALID_VALUES_ERR);
+        return false;
+    }
+
+    if (message) {
+        utils.validateArgumentType(message, "object", null,
+            "sendMessage invalid message parameter",
+            new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+    } else {
+        _errorOccurred(onError, errorcode.INVALID_VALUES_ERR);
+        return false;
+    }
+
+    if (message.type !== _self().TYPE_SMS &&
+        message.type !== _self().TYPE_MMS &&
+        message.type !== _self().TYPE_EMAIL)
+        exception.raise(exception.types.Argument,
+            "sendMessage invalid message.type parameter",
+            new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+
+    if (!_security.all && !_security.sendMessage) {
+        _errorOccurred(onError, errorcode.SECURITY_ERR);
+        return false;
+    }
+
+    TypeCoerce(Message(0)).cast(message);
+    _validateRecipients(message);
+
+    return true;
+}
+
+function _getEachSentStatus(onMessageSentSuccess, onMessageSentError, message,
+                            sucRecipients, failRecipients, recType) {
+    utils.forEach(message[recType], function (recipient) {
+        if (_sentStatus[recipient]) {
+            sucRecipients[recType].push(recipient);
+            if (onMessageSentSuccess) {
+                onMessageSentSuccess(recipient);
+            }
+        } else {
+            failRecipients[recType].push(recipient);
+            if (onMessageSentError) {
+                onMessageSentError(new DeviceApiError(errorcode.UNKNOWN_ERR), recipient);
+            }
+        }
+    });
+}
+
+function _getSentStatus(onSuccess, onError, message, onMessageSentSuccess, onMessageSentError) {
+    var allSentSuccess,
+        sucRecipients = new Recipients(),
+        failRecipients = new Recipients(),
+        duplicate;
+
+    _getEachSentStatus(onMessageSentSuccess, onMessageSentError,
+        message, sucRecipients, failRecipients, "to");
+
+    if (message.type === _self().TYPE_EMAIL) {
+        _getEachSentStatus(onMessageSentSuccess, onMessageSentError,
+            message, sucRecipients, failRecipients, "cc");
+        _getEachSentStatus(onMessageSentSuccess, onMessageSentError,
+            message, sucRecipients, failRecipients, "bcc");
+    }
+
+    allSentSuccess = (failRecipients.total() === 0);
+
+    if (allSentSuccess) {
+        message.folder = _self().FOLDER_SENTBOX;
+    } else if (sucRecipients.total() === 0) {
+        message.folder = _self().FOLDER_DRAFTS;
+    } else {
+        duplicate = utils.copy(message);
+
+        message.to = sucRecipients.to;
+        message.cc = sucRecipients.cc;
+        message.bcc = sucRecipients.bcc;
+        message.folder = _self().FOLDER_SENTBOX;
+
+        duplicate.to = failRecipients.to;
+        duplicate.cc = failRecipients.cc;
+        duplicate.bcc = failRecipients.bcc;
+        duplicate.folder = _self().FOLDER_DRAFTS;
+    }
+
+    _updateDB(message, duplicate);
+
+    if (allSentSuccess) {
+        onSuccess();
+    } else if (onError) {
+        onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
+    }
+}
+
+_self = function () {
+    var messaging = {
+        createMessage: function (type) {
+            type = type | 0;
+
+            if (type < _self().TYPE_SMS || type > _self().TYPE_EMAIL)
+                exception.raise(exception.types.Argument,
+                "type invalid value", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+
+            var msg = new Message(type);
+
+            return msg;
+        },
+
+        sendMessage: function (successCallback, errorCallback, message) {
+            var ret;
+
+            function _sendMessage() {
+                event.trigger("OutsideMessageReceived", [message]);
+
+                return _pendingOperate(_getSentStatus, undefined,
+                    successCallback, errorCallback, message)();
+            }
+
+            function _sendEachMessage() {
+                utils.forEach(successCallback, function (value, key) {
+                    utils.validateArgumentType(value, "function", null,
+                        "sendMessage invalid successCallback." + key + " parameter",
+                        new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+                });
+
+                event.trigger("OutsideMessageReceived", [message]);
+
+                return _pendingOperate(_getSentStatus, undefined,
+                    successCallback.onsuccess, errorCallback, message,
+                    successCallback.onmessagesendsuccess, successCallback.onmessagesenderror)();
+            }
+
+            if (!_isValid(successCallback, errorCallback, message))
+                return null;
+
+            switch (typeof successCallback) {
+            case "function":
+                ret = _sendMessage();
+                break;
+
+            case "object":
+                ret = _sendEachMessage();
+                break;
+            }
+
+            return ret;
+        },
+
+        findMessages: function (successCallback, errorCallback, filter) {
+            function _findMessages() {
+                var message, result = [];
+
+                if (!_security.all && !_security.findMessages)
+                    return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
+
+                utils.forEach(_messages, function (folder) {
+                    utils.forEach(folder, function (messageItem) {
+                        if ((filter                 === undefined || filter === null) ||
+                            (filter.id              === undefined || Filter(filter.id).match(messageItem.id)) &&
+                            (filter.type            === undefined || Filter(filter.type).match(messageItem.type)) &&
+                            (filter.folder          === undefined || Filter(filter.folder).match(messageItem.folder)) &&
+                            (filter.startTimestamp  === undefined || (messageItem.timestamp >= filter.startTimestamp)) &&
+                            (filter.endTimestamp    === undefined || (messageItem.timestamp <= filter.endTimestamp)) &&
+                            (filter.from            === undefined || Filter(filter.from).match(messageItem.from)) &&
+                            (filter.to              === undefined || Filter(filter.to).match(messageItem.to)) &&
+                            (filter.cc              === undefined || Filter(filter.cc).match(messageItem.cc)) &&
+                            (filter.bcc             === undefined || Filter(filter.bcc).match(messageItem.bcc)) &&
+                            (filter.body            === undefined || Filter(filter.body).match(messageItem.body)) &&
+                            (filter.isRead          === undefined || (messageItem.isRead === filter.isRead)) &&
+                            (filter.messagePriority === undefined || (messageItem.priority === filter.messagePriority)) &&
+                            (filter.subject         === undefined || Filter(filter.subject).match(messageItem.subject))) {
+                            message = utils.copy(messageItem);
+                            result.push(message);
+                        }
+                    });
+                });
+                successCallback(result);
+            }
+            return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "findMessages", _pendingOperate(_findMessages));
+        },
+
+        onSMS: function (messageHandler) {
+            return _onMessage("onSMS", messageHandler);
+        },
+
+        onMMS: function (messageHandler) {
+            return _onMessage("onMMS", messageHandler);
+        },
+
+        onEmail: function (messageHandler) {
+            return _onMessage("onEmail", messageHandler);
+        },
+
+        unsubscribe: function (subscriptionHandler) {
+            var onMessage, idSubscribe;
+
+            utils.validateArgumentType(subscriptionHandler, "integer",
+                null, "subscriptionHandler invalid function parameter",
+                new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+
+            for (onMessage in _subscriber) {
+                for (idSubscribe in _subscriber[onMessage]) {
+                    if (idSubscribe == subscriptionHandler) {
+                        delete _subscriber[onMessage][idSubscribe];
+                        return;
+                    }
+                }
+            }
+        },
+
+        handleSubFeatures: function (subFeatures) {
+            for (var subFeature in subFeatures) {
+                if (_security[subFeature].length === 0) {
+                    _security.all = true;
+                    return;
+                }
+                _security.all = false;
+                utils.forEach(_security[subFeature], function (method) {
+                    _security[method] = true;
+                });
+            }
+        }
+    };
+
+    messaging.__defineGetter__("TYPE_SMS", function () {
+        return 1;
+    });
+
+    messaging.__defineGetter__("TYPE_MMS", function () {
+        return 2;
+    });
+
+    messaging.__defineGetter__("TYPE_EMAIL", function () {
+        return 3;
+    });
+
+    messaging.__defineGetter__("FOLDER_INBOX", function () {
+        return 1;
+    });
+
+    messaging.__defineGetter__("FOLDER_OUTBOX", function () {
+        return 2;
+    });
+
+    messaging.__defineGetter__("FOLDER_DRAFTS", function () {
+        return 3;
+    });
+
+    messaging.__defineGetter__("FOLDER_SENTBOX", function () {
+        return 4;
+    });
+
+    if (!_initialized)
+        _initialize();
+
+    return messaging;
+};
+
+MessageSendCallback = {
+    onsuccess: function () {},
+    onmessagesendsuccess: function (recipient) {},
+    onmessagesenderror: function (error, recipient) {}
+};
+
+Message = function (type) {
+    this.id = Math.uuid(null, 16);
+    this.type = type;
+    this.folder = 0;
+    this.timestamp = new Date();
+    this.from = "";
+    this.to = [""];
+    this.cc = [""];
+    this.bcc = [""];
+    this.body = "";
+    this.isRead = false;
+    this.priority = false;
+    this.subject = "";
+    this.attachments = [""];
+
+    this.update = function (successCallback, errorCallback) {
+        function _update() {
+            var isFound = false;
+
+            if (!_security.all && !_security.update)
+                return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
+
+            TypeCoerce(new Message(0)).cast(this);
+            _get();
+            utils.forEach(_messages[this.folder], function (messageItem) {
+                if (messageItem.id === this.id) {
+                    !this.isRead || (messageItem.isRead = this.isRead);
+                    if (this.folder === _self().FOLDER_DRAFTS) {
+                        !this.type        || (messageItem.type        = this.type);
+                        !this.to          || (messageItem.to          = utils.copy(this.to));
+                        !this.cc          || (messageItem.cc          = utils.copy(this.cc));
+                        !this.bcc         || (messageItem.bcc         = utils.copy(this.bcc));
+                        !this.body        || (messageItem.body        = this.body);
+                        !this.priority    || (messageItem.priority    = this.priority);
+                        !this.subject     || (messageItem.subject     = this.subject);
+                        !this.attachments || (messageItem.attachments = utils.copy(this.attachments));
+                    }
+                    isFound = true;
+                }
+            });
+
+            if (isFound) {
+                _save();
+                successCallback();
+            } else {
+                _errorOccurred(errorCallback, errorcode.NOT_FOUND_ERR);
+            }
+        }
+        return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "update", _pendingOperate(_update, this));
+    };
+};
+
+MessageFilter = {
+    id: "",
+    type: [0],
+    folder: [0],
+    startTimestamp: new Date(),
+    endTimestamp: new Date(),
+    from: "",
+    to: [""],
+    cc: [""],
+    bcc: [""],
+    body: "",
+    isRead: false,
+    messagePriority: false,
+    subject: ""
+};
+
+Recipients = function () {
+    this.to  = [];
+    this.cc  = [];
+    this.bcc = [];
+
+    this.total = function () {
+        return (this.to.length + this.cc.length + this.bcc.length);
+    };
+};
+
+event.on("MessageReceived", function (message) {
+    var onMessage;
+
+    switch (message.type) {
+    case "sms":
+        message.type = _self().TYPE_SMS;
+        onMessage = "onSMS";
+        break;
+
+    case "mms":
+        message.type = _self().TYPE_MMS;
+        onMessage = "onMMS";
+        break;
+
+    case "email":
+        message.type = _self().TYPE_EMAIL;
+        onMessage = "onEmail";
+        break;
+
+    default:
+        break;
+    }
+
+    message.folder = _self().FOLDER_INBOX;
+    _processAttachments(message);
+    _updateDB(message);
+    utils.forEach(_subscriber[onMessage], function (subscriberCallback) {
+        subscriberCallback(message);
+    });
+});
+
+event.on("MessageSent", function (sentStatus) {
+    _sentStatus = sentStatus;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/2.0/calendar', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    constants = require('ripple/constants'),
+    errorcode = require('ripple/platform/wac/2.0/errorcode'),
+    PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
+    PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
+    wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
+    _console = require('ripple/console'),
+    DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
+    _SIM_CALENDAR = 0, _DEVICE_CALENDAR = 1,
+    _NO_RECURRENCE = 0, _DAILY_RECURRENCE = 1, _WEEKLY_RECURRENCE = 2,
+    _MONTHLY_RECURRENCE = 3, _YEARLY_RECURRENCE = 4,
+    _TENTATIVE_STATUS = 0, _CONFIRMED_STATUS = 1, _CANCELLED_STATUS = 2,
+    _NO_ALARM = 0, _SILENT_ALARM = 1, _SOUND_ALARM = 2,
+    _calendars = [], _DB_CALENDARS_KEY = "wac2-db-calendars",
+    _FAKEWAITTIME = 5, _FAKE_LONG_WAITTIME = 10,
+    _save_calendars, _eventPropCheck, _eventFilterCheck,
+    _addEventAllowed = true, _deleteEventAllowed = true,
+    _updateEventAllowed = true, _findEventsAllowed = true,
+    CalendarEventProperties, Calendar, CalendarEvent;
+
+_save_calendars = function (_name, _type, _events) {
+    var i;
+    for (i = 0; i < _calendars.length; i++) {
+        if (_calendars[i].name === _name && _calendars[i].type === _type) {
+            _calendars[i].events = _events;
+            break;
+        }
+    }
+    db.saveObject(_DB_CALENDARS_KEY, _calendars);
+};
+
+_eventPropCheck = function (prop, dst) {
+    var i;
+    if (prop.description !== null && prop.description !== undefined) {
+        dst.description = String(prop.description);
+    }
+    if (prop.summary !== null && prop.summary !== undefined) {
+        dst.summary = String(prop.summary);
+    } 
+    if (prop.startTime !== null && prop.startTime !== undefined) {
+        if (!wac2_utils.isValidDate(prop.startTime)) {
+            return false;
+        }
+        dst.startTime = new Date(prop.startTime);
+    }
+    dst.duration = prop.duration | 0;
+    if (prop.location !== null && prop.location !== undefined) {
+        dst.location = String(prop.location);
+    }
+    if (prop.categories !== null && prop.categories !== undefined) {
+        if (!wac2_utils.isValidArray(prop.categories))  {
+            return false;
+        }
+        dst.categories = [];
+        for (i = 0; i < prop.categories.length; i++) {
+            dst.categories.push(String(prop.categories[i]));
+        }
+    }
+    if (prop.recurrence !== null && prop.recurrence !== undefined) {
+        if (prop.recurrence === _NO_RECURRENCE ||
+            prop.recurrence === _DAILY_RECURRENCE ||
+            prop.recurrence === _WEEKLY_RECURRENCE ||
+            prop.recurrence === _MONTHLY_RECURRENCE ||
+            prop.recurrence === _YEARLY_RECURRENCE) {
+            dst.recurrence = prop.recurrence | 0;
+        } else {
+            return false;
+        }
+    }
+    if (dst.recurrence === _NO_RECURRENCE) {
+        dst.expires = null;
+        dst.interval = null;
+    } else {
+        // expires and interval matters when recurrence is not NO_RECURRENCE
+        if (prop.expires !== null && prop.expires !== undefined) {
+            if (!wac2_utils.isValidDate(prop.expires)) {
+                return false;
+            }
+            dst.expires = new Date(prop.expires);
+        }
+        // expires === undefined -> to recur indefinitely
+        // expires === null -> keep dst.expires unchanged, even it's null
+        if (prop.expires === undefined) {
+            dst.expires = null;
+        }
+        if (prop.interval !== null && prop.interval !== undefined) {
+            dst.interval = prop.interval | 0;
+        }
+    }
+
+    if (prop.status !== null && prop.status !== undefined) {
+        if (prop.status === _TENTATIVE_STATUS ||
+            prop.status === _CONFIRMED_STATUS ||
+            prop.status === _CANCELLED_STATUS) {
+            dst.status = prop.status | 0;
+        } else {
+            return false;
+        }
+    }
+
+    if (prop.alarmType !== null && prop.alarmType !== undefined) {
+        if (prop.alarmType === _NO_ALARM ||
+            prop.alarmType === _SILENT_ALARM ||
+            prop.alarmType === _SOUND_ALARM) {
+            dst.alarmType = prop.alarmType;
+        } else {
+            return false;
+        }
+    } 
+    if (dst.alarmType !== _NO_ALARM && prop.alarmTrigger !== undefined && prop.alarmTrigger !== undefined) {
+        dst.alarmTrigger = prop.alarmTrigger | 0;
+    }
+};
+
+_eventFilterCheck = function (filter) {
+    if (filter.id !== undefined && filter.id !== null) {
+        filter.id = String(filter.id);
+    } else {
+        filter.id = undefined;
+    }
+    if (filter.summary !== undefined && filter.summary !== null) {
+        filter.summary = String(filter.summary);
+    } else {
+        filter.summary = undefined;
+    }
+    if (filter.description !== undefined && filter.description !== null) {
+        filter.description = String(filter.description);
+    } else {
+        filter.description = undefined;
+    }
+    if (filter.location !== undefined && filter.location !== null) {
+        filter.location = String(filter.location);
+    } else {
+        filter.location = undefined;
+    }
+    if (filter.catetory !== undefined && filter.catetory !== null) {
+        filter.catetory = String(filter.catetory);
+    } else {
+        filter.catetory = undefined;
+    }
+    if (filter.status !== undefined && filter.status !== null) {
+        var i;
+        if (!wac2_utils.isValidArray(filter.status))  {
+            return false;
+        }
+        for (i = 0; i < filter.status.length; i++) {
+            filter.status[i] = filter.status[i] | 0;
+            if (filter.status[i] > _CANCELLED_STATUS || filter.status[i] < _TENTATIVE_STATUS)
+                return false;
+        }
+    } else {
+        filter.status = undefined;
+    }
+    if (filter.initialStartDate !== undefined && filter.initialStartDate !== null) {
+        if (!wac2_utils.isValidDate(filter.initialStartDate)) {
+            return false;
+        }
+        filter.initialStartDate = new Date(filter.initialStartDate);
+    } else {
+        filter.initialStartDate = undefined;
+    }
+    if (filter.endStartDate !== undefined && filter.endStartDate !== null) {
+        if (!wac2_utils.isValidDate(filter.endStartDate)) {
+            return false;
+        }
+        filter.endStartDate = new Date(filter.endStartDate);
+    } else {
+        filter.endStartDate = undefined;
+    }
+    return true;
+};
+
+CalendarEventProperties = function (prop) {
+    var _self;
+    _self = {
+        description : "",
+        summary : "",
+        startTime : new Date(),
+        duration : 0,
+        location : "",
+        categories : undefined,
+        recurrence : _NO_RECURRENCE,
+        expires : null,  // ignored if recurrence == NO_RECURRENCE
+        interval : null, // ignored if recurrence == NO_RECURRENCE
+        status : _CONFIRMED_STATUS,
+        alarmTrigger : 0,
+        alarmType : _NO_ALARM
+    };
+    if (prop) {
+        if (_eventPropCheck(prop, _self) === false) {
+            return undefined;
+        }
+    }
+    return _self;
+};
+
+CalendarEvent = function (prop, genNewID) {
+    var id, _self = new CalendarEventProperties(prop);
+
+    /* if error occurs during checking, _self is an empty object.
+       so i randomly pick description to check if property check fails */
+    if (_self.description === undefined) {
+        return undefined;
+    }
+
+    if (genNewID === true) {
+        id = Math.uuid(undefined, 16);
+    } else {
+        id = prop.id;
+    }
+    _self.__defineGetter__("id", function () {
+        return id;
+    });
+    return _self;
+};
+
+Calendar = function (type, name, events) {
+    var _type = type,
+        _name = name,
+        _events = events, _self;
+
+    _self = {
+        createEvent: function (evtProp) {
+            var rst = {};
+            rst = new CalendarEventProperties(evtProp);
+            /* if error occurs during checking, rst is an empty object.
+               so i randomly pick description to check if property check fails */
+            if (rst.description === undefined) {
+                exception.raise(exception.types.Argument, "EventProperties: input parameter contains invalid values", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                return undefined;
+            } else {
+                return rst;
+            }
+        },
+
+        addEvent: function (onSuccess, onError, calEvent) {
+            var pendingOperation, pendingObj = {},
+                newEvent = {}, _doAddEvent, _calEvent = Object(calEvent);
+
+            _doAddEvent = function () {
+                if (!_addEventAllowed) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                newEvent = new CalendarEvent(_calEvent, true);
+                /* if newEvent.id === undefined,
+                   means somthing wrong in calEvent  */
+                if (newEvent.id === undefined) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                pendingObj = new PendingObject();
+                pendingObj.pendingID = setTimeout(function () {
+                    pendingObj.setCancelFlag(false);
+                    _events[newEvent.id] = newEvent;
+                    _save_calendars(_name, _type, _events);
+                    onSuccess(new CalendarEvent(newEvent), false);
+                }, _FAKEWAITTIME);
+                pendingOperation = new PendingOperation(pendingObj);
+                return pendingOperation;
+            };
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:addEvent", _doAddEvent);
+        },
+
+        updateEvent: function (onSuccess, onError, calEvent) {
+            var pendingOperation, pendingObj = {},
+                chkEvent, _doUpdateEvent, _calEvent = Object(calEvent);
+
+            _doUpdateEvent = function () {
+                if (!_updateEventAllowed) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                if (!_events[_calEvent.id]) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                chkEvent = new CalendarEvent(_events[_calEvent.id], false);
+                /* _eventPropCheck will also update chkEvent btw */
+                if (_eventPropCheck(_calEvent, chkEvent) === false) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                pendingObj = new PendingObject();
+                pendingObj.pendingID = setTimeout(function () {
+                    pendingObj.setCancelFlag(false);
+
+                    _events[chkEvent.id] = chkEvent;
+                    _save_calendars(_name, _type, _events);
+                    onSuccess();
+                }, _FAKEWAITTIME);
+                pendingOperation = new PendingOperation(pendingObj);
+                return pendingOperation;
+            };
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:updateEvent", _doUpdateEvent);
+        },
+
+        deleteEvent: function (onSuccess, onError, id) {
+            var pendingOperation, pendingObj = {},
+                _doDeleteEvent;
+
+            _doDeleteEvent = function () {
+                /* according to spec  "If any of the input parameters are not 
+                   compatible with the expected type for that parameter, 
+                   a DeviceAPIError with code TYPE_MISMATCH_ERR MUST be 
+                   synchronously thrown." 
+                   so an error is raised synchronously */
+                utils.validateArgumentType(id, "string", null,
+                                       "Calendar:deleteEvent: " + " invalid id parameter",
+                                       new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+
+                if (!_deleteEventAllowed) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                if (!_events[id]) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                pendingObj = new PendingObject();
+                pendingObj.pendingID = setTimeout(function () {
+                    pendingObj.setCancelFlag(false);
+
+                    delete _events[id];
+                    _save_calendars(_name, _type, _events);
+                    onSuccess();
+                }, _FAKEWAITTIME);
+                pendingOperation = new PendingOperation(pendingObj);
+                return pendingOperation;
+            };
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:deleteEvent", _doDeleteEvent);
+        },
+
+        findEvents: function (onSuccess, onError, eventFilter) {
+            var pendingOperation, pendingObj = {}, i,
+                tmp = [], valid_tmp = false, rst = [], _doFindEvents,
+                _eventFilter = Object(eventFilter);
+
+            _doFindEvents = function () {
+                if (!_eventFilterCheck(_eventFilter)) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                if (!_findEventsAllowed) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                pendingObj = new PendingObject();
+                pendingObj.pendingID = setTimeout(function () {
+                    pendingObj.setCancelFlag(false);
+                    if (_eventFilter.id !== undefined) {
+                        tmp = wac2_utils.matchOptionString(_events, "id", _eventFilter.id);
+                        valid_tmp = true;
+                    }
+                    if (_eventFilter.summary !== undefined) {
+                        if (valid_tmp) {
+                            tmp = wac2_utils.matchOptionString(tmp, "summary", _eventFilter.summary);
+                        } else {
+                            tmp = wac2_utils.matchOptionString(_events, "summary", _eventFilter.summary);
+                            valid_tmp = true;
+                        }
+                    }
+                    if (_eventFilter.description !== undefined) {
+                        if (valid_tmp) {
+                            tmp = wac2_utils.matchOptionString(tmp, "description", _eventFilter.description);
+                        } else {
+                            tmp = wac2_utils.matchOptionString(_events, "description", _eventFilter.description);
+                            valid_tmp = true;
+                        }
+                    }
+                    if (_eventFilter.location !== undefined) {
+                        if (valid_tmp) {
+                            tmp = wac2_utils.matchOptionString(tmp, "location", _eventFilter.location);
+                        } else {
+                            tmp = wac2_utils.matchOptionString(_events, "location", _eventFilter.location);
+                            valid_tmp = true;
+                        }
+                    }
+                    if (_eventFilter.category !== undefined) {
+                        if (valid_tmp) {
+                            tmp = wac2_utils.matchOptionArrayString(tmp, "categories", _eventFilter.category);
+                        } else {
+                            tmp = wac2_utils.matchOptionArrayString(_events, "categories", _eventFilter.category);
+                            valid_tmp = true;
+                        }
+                    }
+                    if (_eventFilter.status !== undefined) {
+                        if (valid_tmp) {
+                            tmp = wac2_utils.matchOptionShortArray(tmp, "status", _eventFilter.status);
+                        } else {
+                            tmp = wac2_utils.matchOptionShortArray(_events, "status", _eventFilter.status);
+                            valid_tmp = true;
+                        }
+                    }
+                    if (_eventFilter.initialStartDate !== undefined ||
+                        _eventFilter.endStartDate !== undefined) {
+                        if (valid_tmp) {
+                            tmp = wac2_utils.matchOptionDate(tmp, "startTime", _eventFilter.initialStartDate, _eventFilter.endStartDate);
+                        } else {
+                            tmp = wac2_utils.matchOptionDate(_events, "startTime", _eventFilter.initialStartDate, _eventFilter.endStartDate);
+                            valid_tmp = true;
+                        }
+                    }
+
+                    // to make id readonly
+                    if (valid_tmp) {
+                        for (i = 0; i < tmp.length; i++) {
+                            rst.push(new CalendarEvent(tmp[i], false));
+                        }
+                    } else {
+                        for (var e in _events) {
+                            rst.push(new CalendarEvent(_events[e], false));
+                        }
+                    }
+                    onSuccess(rst);
+                }, _FAKE_LONG_WAITTIME);
+                pendingOperation = new PendingOperation(pendingObj);
+                return pendingOperation;
+            };
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:findEvent", _doFindEvents);
+        },
+    };
+    _self.__defineGetter__("type", function () {
+        return _type;
+    });
+    _self.__defineGetter__("name", function () {
+        return name;
+    });
+    return _self;
+};
+
+module.exports = function () {
+    this.__defineGetter__("SIM_CALENDAR", function () {
+        return 0;
+    });
+    this.__defineGetter__("DEVICE_CALENDAR", function () {
+        return 1;
+    });
+    this.__defineGetter__("NO_RECURRENCE", function () { 
+        return 0;
+    });
+    this.__defineGetter__("DAILY_RECURRENCE", function () {
+        return 1;
+    });
+    this.__defineGetter__("WEEKLY_RECURRENCE", function () {
+        return 2;
+    });
+    this.__defineGetter__("MONTHLY_RECURRENCE", function () {
+        return 3;
+    });
+    this.__defineGetter__("YEARLY_RECURRENCE", function () {
+        return 4;
+    });
+    this.__defineGetter__("TENTATIVE_STATUS", function () {
+        return 0;
+    });
+    this.__defineGetter__("CONFIRMED_STATUS", function () {
+        return 1;
+    });
+    this.__defineGetter__("CANCELLED_STATUS", function () {
+        return 2;
+    });
+    this.__defineGetter__("NO_ALARM", function () {
+        return 0;
+    });
+    this.__defineGetter__("SILENT_ALARM", function () {
+        return 1;
+    });
+    this.__defineGetter__("SOUND_ALARM", function () {
+        return 2;
+    });
+
+    this.getCalendars = function (onSuccess, onError) {
+        var i, pendingOperation, pendingObj = {}, cal, _doGetCalendars;
+
+        _doGetCalendars = function () {
+            pendingObj = new PendingObject();
+
+            pendingObj.pendingID = setTimeout(function () {
+                pendingObj.setCancelFlag(false);
+                cal = db.retrieveObject(_DB_CALENDARS_KEY) || [];
+                _calendars = [];
+                if (cal.length === 0) {
+                    _calendars.push(new Calendar(_SIM_CALENDAR, "sim cal", {}));
+                    _calendars.push(new Calendar(_DEVICE_CALENDAR, "dev cal", {}));
+                } else {
+                    for (i = 0; i < cal.length; i++) {
+                        /* after getting Date out of DB, Date will become 
+                           a string, so need to recast it back to Date */
+                        /* NOTE: id becomes writable, so need to recast it
+                           before passing to application */
+                        for (var e in cal[i].events) {
+                            if ((cal[i].events[e].startTime !== undefined) &&
+                                cal[i].events[e].startTime !== null) {
+                                cal[i].events[e].startTime = new Date(cal[i].events[e].startTime);
+                            }
+                            if ((cal[i].events[e].expires !== undefined) &&
+                                cal[i].events[e].expires !== null) {
+                                cal[i].events[e].expires = new Date(cal[i].events[e].expires);
+                            }
+                        }
+                        _calendars.push(new Calendar(cal[i].type, cal[i].name, cal[i].events));
+                    }
+                }
+                if (_calendars.length !== 0) {
+                    onSuccess(utils.copy(_calendars));
+                } else {
+                    if (onError) {
+                        onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
+                    }
+                }
+            }, _FAKEWAITTIME);
+            pendingOperation = new PendingOperation(pendingObj);
+            return pendingOperation;
+        };
+    
+        return wac2_utils.validateTypeMismatch(onSuccess, onError, "getCalendars", _doGetCalendars);
+    };
+
+    this.handleSubFeatures = function (subFeatures) {
+        if (wac2_utils.isEmptyObject(subFeatures) ||
+            subFeatures["http://wacapps.net/api/pim.calendar"] ||
+            (subFeatures["http://wacapps.net/api/pim.calendar.read"] &&
+            subFeatures["http://wacapps.net/api/pim.calendar.write"])) {
+            return;
+        } 
+        if (subFeatures["http://wacapps.net/api/pim.calendar.read"]) {
+            _addEventAllowed = false;
+            _deleteEventAllowed = false;
+            _updateEventAllowed = false;
+            return;
+        } 
+        if (subFeatures["http://wacapps.net/api/pim.calendar.write"]) {
+            _findEventsAllowed = false;
+            return;
+        } 
+        _console.warn("WAC-2.0-Calendar-handleSubFeatures: something wrong");
+    };
+};
+
+});
+require.define('ripple/platform/wac/2.0/task', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    _console = require('ripple/console'),
+    exception = require('ripple/exception'),
+    errorcode = require('ripple/platform/wac/2.0/errorcode'),
+    wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
+    PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
+    DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
+    PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
+    Task, TaskList, _get,
+    _ID_WITHOUT = 0, _ID_GEN_NEW = 1, _ID_FROM_PROP = 2,
+    _SIM_TASK_LIST = 0, _DEVICE_TASK_LIST = 1,
+    _HIGH_PRIORITY = 0, _MEDIUM_PRIORITY = 1, _LOW_PRIORITY = 2,
+    _STATUS_COMPLETED = 0, _STATUS_NEEDS_ACTION = 1, _STATUS_IN_PROCESS = 2, _STATUS_CANCELLED = 3,
+    _TASK_OBJECTS = "wac2.0-pim-task-objects",
+    _addTaskAllowed = true, _deleteTaskAllowed = true,
+    _updateTaskAllowed = true, _findTasksAllowed = true;
+
+
+module.exports = function () {
+    var _taskListArray = [],
+        _PENDING_TIME = 10;
+
+    function _pendingOperate(operate) {
+        var pendingObj, pendingOperation, i, argumentVector = [];
+
+        for (i = 0; i < arguments.length - 1; i++)
+            argumentVector[i] = arguments[i + 1];
+
+        pendingObj = new PendingObject();
+
+        pendingObj.pendingID = window.setTimeout(function () {
+            pendingObj.setCancelFlag(false);
+            operate.apply(this, argumentVector);
+        }, _PENDING_TIME);
+
+        pendingOperation = new PendingOperation(pendingObj);
+
+        return pendingOperation;
+    }
+
+    /* taskProperties attribute check & paste */
+    function _checkAndPasteProperties(p, dst) {
+
+        if (p.summary !== null && p.summary !== undefined)
+            dst.summary = String(p.summary);
+
+        if (p.description !== null && p.description !== undefined)
+            dst.description = String(p.description);
+
+        if (p.status !== null && p.status !== undefined) {
+            if (p.status === _STATUS_COMPLETED ||
+                p.status === _STATUS_NEEDS_ACTION ||
+                p.status === _STATUS_IN_PROCESS ||
+                p.status === _STATUS_CANCELLED) {
+                dst.status = p.status;
+            } else
+                return false;
+        }
+
+        if (p.priority !== null && p.priority !== undefined) {
+            if (p.priority === _HIGH_PRIORITY ||
+                p.priority === _MEDIUM_PRIORITY ||
+                p.priority === _LOW_PRIORITY) {
+                dst.priority = p.priority;
+            } else
+                return false;
+        }
+
+        if (p.dueDate !== null && p.dueDate !== undefined) {
+            if (!wac2_utils.isValidDate(p.dueDate))
+                return false;
+            dst.dueDate = new Date(p.dueDate);
+        }
+
+        /* dueDate is a option properties.
+           "The default value is undefined.
+             If no value is provided, the task has no due date."
+           If p.dueDate is set its default value 'undefined',
+           we assign default value to dst.dueDate */
+        if (p.dueDate === undefined) {
+            dst.dueDate = undefined;
+        }
+
+        return true;
+    }
+
+    function _taskFilterCheck(filter) {
+        var i;
+        if (filter.id !== undefined && filter.id !== null) {
+            filter.id = String(filter.id);
+        } else {
+            filter.id = undefined;
+        }
+        if (filter.summary !== undefined && filter.summary !== null) {
+            filter.summary = String(filter.summary);
+        } else {
+            filter.summary = undefined;
+        }
+        if (filter.description !== undefined && filter.description !== null) {
+            filter.description = String(filter.description);
+        } else {
+            filter.description = undefined;
+        }
+        if (filter.status !== undefined && filter.status !== null) {
+            if (!wac2_utils.isValidArray(filter.status))  {
+                return false;
+            }
+            for (i = 0; i < filter.status.length; i++) {
+                filter.status[i] = filter.status[i] | 0;
+                if (filter.status[i] !== _STATUS_COMPLETED &&
+                    filter.status[i] !== _STATUS_NEEDS_ACTION &&
+                    filter.status[i] !== _STATUS_IN_PROCESS &&
+                    filter.status[i] !== _STATUS_CANCELLED) {
+                    return false;
+                }
+            }
+        } else {
+            filter.status = undefined;
+        }
+        if (filter.priority !== undefined && filter.priority !== null) {
+            if (!wac2_utils.isValidArray(filter.priority))  {
+                return false;
+            }
+            for (i = 0; i < filter.priority.length; i++) {
+                filter.priority[i] = filter.priority[i] | 0;
+                if (filter.priority[i] !== _HIGH_PRIORITY &&
+                    filter.priority[i] !== _MEDIUM_PRIORITY &&
+                    filter.priority[i] !== _LOW_PRIORITY) {
+                    return false;
+                }
+            }
+        } else {
+            filter.priority = undefined;
+        }
+        if (filter.dueDate !== undefined && filter.dueDate !== null) {
+            if (!wac2_utils.isValidDate(filter.dueDate)) {
+                return false;
+            }
+            filter.dueDate = new Date(filter.dueDate);
+        } else {
+            filter.dueDate = undefined;
+        }
+        return true;
+    }
+
+    function TaskProperties(prop) {
+        var _self;
+        _self = {
+            priority : _LOW_PRIORITY,
+            description : "",
+            summary : "",
+            dueDate : undefined,
+            status : _STATUS_NEEDS_ACTION
+        };
+        if (prop) {
+            if (_checkAndPasteProperties(prop, _self) === false)
+                return undefined;
+        }
+        return _self;
+    }
+
+    function Task(prop, idChoice) {
+        var id, _self = new TaskProperties(prop);
+        /* if error occurs during checking, _self is an empty object.
+           so i randomly pick description to check if property check fails */
+        if (_self.description === undefined)
+            return undefined;
+
+        switch (idChoice) {
+        case _ID_WITHOUT:
+            // do nothing
+            break;
+        case _ID_GEN_NEW:
+            id = Math.uuid(undefined, 16);
+            _self.__defineGetter__("id", function () {
+                return id;
+            });
+            break;
+        case _ID_FROM_PROP:
+            id = String(prop.id);
+            _self.__defineGetter__("id", function () {
+                return id;
+            });
+            break;
+        }
+
+        return _self;
+    }
+
+    function _get() {
+        var taskListArray = [],
+            data = db.retrieveObject(_TASK_OBJECTS);
+        utils.forEach(data, function (taskList) {
+            for (var t in taskList._list) {
+                if (taskList._list[t].dueDate !== undefined &&
+                    taskList._list[t].dueDate !== null)
+                    taskList._list[t].dueDate = new Date(taskList._list[t].dueDate);
+            }
+            taskListArray.push(new TaskList(taskList._list, taskList.type, taskList.name));
+        });
+
+        /* add default taskList if taskListArray is empty */
+        if (taskListArray.length === 0) {
+            taskListArray = [new TaskList({}, 0, "Office tasks"), new TaskList({}, 1, "Home tasks")];
+        }
+
+        return taskListArray;
+    }
+
+    function _save() {
+        db.saveObject(_TASK_OBJECTS, _taskListArray);
+    }
+
+    function TaskList(taskList, type, name) {
+        var task;
+        this._list = taskList;
+        this.type = type;
+        this.name = name;
+
+        this.createTask = function (properties) {
+            task = new Task(properties, _ID_WITHOUT);
+            /* if error occurs during checking, task is an empty object.
+               so i randomly pick summary to check if property check fails */
+            if (task.summary === undefined) {
+                exception.raise(exception.types.Argument,
+                        "EventProperties: input parameter contains invalid values",
+                        new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                return undefined;
+            }
+            return task;
+        };
+
+        this.addTask = function (onSuccess, onError, task) {
+            var inner = this,
+                newTask, _task = Object(task);
+            function _addTask() {
+                var ret;
+                if (!_addTaskAllowed) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                newTask = new Task(_task, _ID_GEN_NEW);
+                /* if error occurs during checking, newTask is an empty object.
+                    so i randomly pick id to check if property check fails */
+                if (newTask.id === undefined) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                ret = _pendingOperate(function () {
+                    inner._list[newTask.id] = newTask;
+                    _save();
+                    onSuccess(new Task(newTask, _ID_FROM_PROP));
+                });
+            }
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "addTask", _addTask);
+        };
+
+        this.updateTask = function (onSuccess, onError, task) {
+            var inner = this,
+                newTask, _task = Object(task);
+            function _updateTask() {
+                var ret;
+                if (!_updateTaskAllowed) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                if (_checkAndPasteProperties(_task, _task) === false) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+
+                ret = _pendingOperate(function () {
+                    if (inner._list[_task.id]) {
+                        newTask = new Task(inner._list[_task.id], _ID_FROM_PROP);
+                        /* Don't need to double check the return of _checkAndPasteProperties 
+                           _task has been checked & pasted already */
+                        _checkAndPasteProperties(_task, newTask);
+                        inner._list[newTask.id] = newTask;
+                        _save();
+                        onSuccess();
+                    } else {
+                        if (onError) {
+                            onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
+                        }
+                    }
+                });
+                return ret;
+            }
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "updateTask", _updateTask);
+        };
+
+        this.deleteTask = function (onSuccess, onError, id) {
+            var inner = this;
+            function _deleteTask() {
+                var ret;
+                /* according to spec  "If any of the input parameters are not 
+                   compatible with the expected type for that parameter, 
+                   a DeviceAPIError with code TYPE_MISMATCH_ERR MUST be 
+                   synchronously thrown." so an error is raised synchronously */
+                utils.validateArgumentType(id, "string", null,
+                        "Task:deleteTask: " + " invalid id parameter",
+                        new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+                if (!_deleteTaskAllowed) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                ret = _pendingOperate(function () {
+                    if (inner._list[id]) {
+                        delete inner._list[id];
+                        _save();
+                        onSuccess();
+                    } else {
+                        if (onError)
+                            onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
+                    }
+                });
+                return ret;
+            }
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "deleteTask", _deleteTask);
+        };
+
+        this.findTasks = function (onSuccess, onError, filter) {
+            var inner = this, _filter = Object(filter), tmp = [], rst = [], valid_tmp = false;
+            function _findTasks() {
+                var ret;
+                if (!_taskFilterCheck(_filter)) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                if (!_findTasksAllowed) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.SECURITY_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }
+                ret = _pendingOperate(function () {
+                    var i, e;
+                    if (_filter.id !== undefined) {
+                        tmp = wac2_utils.matchOptionString(inner._list, "id", _filter.id);
+                        valid_tmp = true;
+                    }
+                    if (_filter.summary !== undefined) {
+                        if (valid_tmp) {
+                            tmp = wac2_utils.matchOptionString(tmp, "summary", _filter.summary);
+                        } else {
+                            tmp = wac2_utils.matchOptionString(inner._list, "summary", _filter.summary);
+                            valid_tmp = true;
+                        }
+                    }
+                    if (_filter.description !== undefined) {
+                        if (valid_tmp) {
+                            tmp = wac2_utils.matchOptionString(tmp, "description", _filter.description);
+                        } else {
+                            tmp = wac2_utils.matchOptionString(inner._list, "description", _filter.description);
+                            valid_tmp = true;
+                        }
+                    }
+                    if (_filter.status !== undefined) {
+                        if (valid_tmp) {
+                            tmp = wac2_utils.matchOptionShortArray(tmp, "status", _filter.status);
+                        } else {
+                            tmp = wac2_utils.matchOptionShortArray(inner._list, "status", _filter.status);
+                            valid_tmp = true;
+                        }
+                    }
+                    if (_filter.priority !== undefined) {
+                        if (valid_tmp) {
+                            tmp = wac2_utils.matchOptionShortArray(tmp, "priority", _filter.priority);
+                        } else {
+                            tmp = wac2_utils.matchOptionShortArray(inner._list, "priority", _filter.priority);
+                            valid_tmp = true;
+                        }
+                    }
+                    if (_filter.initialDueDate !== undefined ||
+                        _filter.endDueDate !== undefined) {
+                        if (valid_tmp) {
+                            tmp = wac2_utils.matchOptionDate(tmp, "dueDate", _filter.initialDueDate, _filter.endDueDate);
+                        } else {
+                            tmp = wac2_utils.matchOptionDate(inner._list, "dueDate", _filter.initialDueDate, _filter.endDueDate);
+                            valid_tmp = true;
+                        }
+                    }
+
+                    if (valid_tmp) {
+                        for (i = 0; i < tmp.length; i++) {
+                            rst.push(new Task(tmp[i], _ID_FROM_PROP));
+                        } 
+                    } else {
+                        for (e in inner._list) {
+                            rst.push(new Task(inner._list[e], _ID_FROM_PROP));
+                        }
+                    }
+                    onSuccess(rst);
+                });
+                return ret;
+            }
+
+            return wac2_utils.validateTypeMismatch(onSuccess, onError, "findTasks", _findTasks);
+        };
+    }
+
+    this.getTaskLists = function (onSuccess, onError) {
+        function _getTaskLists() {
+            var ret;
+            ret = _pendingOperate(function () {
+                if (_taskListArray.length === 0) {
+                    _taskListArray = _get();
+                }
+                onSuccess(_taskListArray);
+            }, 1);
+            return ret;
+        }
+
+        return wac2_utils.validateTypeMismatch(onSuccess, onError, "getTaskLists", _getTaskLists);
+    };
+
+    this.__defineGetter__("SIM_TASK_LIST", function () {
+        return 0;
+    });
+    this.__defineGetter__("DEVICE_TASK_LIST", function () {
+        return 1;
+    });
+    this.__defineGetter__("HIGH_PRIORITY", function () {
+        return 0;
+    });
+    this.__defineGetter__("MEDIUM_PRIORITY", function () {
+        return 1;
+    });
+    this.__defineGetter__("LOW_PRIORITY", function () {
+        return 2;
+    });
+    this.__defineGetter__("STATUS_COMPLETED", function () {
+        return 0;
+    });
+    this.__defineGetter__("STATUS_NEEDS_ACTION", function () {
+        return 1;
+    });
+    this.__defineGetter__("STATUS_IN_PROCESS", function () {
+        return 2;
+    });
+    this.__defineGetter__("STATUS_CANCELLED", function () {
+        return 3;
+    });
+
+    this.handleSubFeatures = function (subFeatures) {
+        if (wac2_utils.isEmptyObject(subFeatures) ||
+            subFeatures["http://wacapps.net/api/pim.task"] ||
+            (subFeatures["http://wacapps.net/api/pim.task.read"] &&
+            subFeatures["http://wacapps.net/api/pim.task.write"])) {
+            return;
+        }
+        if (subFeatures["http://wacapps.net/api/pim.task.read"] &&
+           !subFeatures["http://wacapps.net/api/pim.task.write"]) {
+            _addTaskAllowed = false;
+            _deleteTaskAllowed = false;
+            _updateTaskAllowed = false;
+            return;
+        }
+        if (subFeatures["http://wacapps.net/api/pim.task.write"] &&
+           !subFeatures["http://wacapps.net/api/pim.task.read"]) {
+            _findTasksAllowed = false;
+            return;
+        }
+        _console.warn("WAC-2.0-Task-handleSubFeatures: something wrong");
+    };
+
+};
+
+
+});
+require.define('ripple/platform/wac/2.0/wac2_utils', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var utils = require('ripple/utils'),
+    errorcode = require('ripple/platform/wac/2.0/errorcode'),
+    DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror');
+
+module.exports = {
+    _wac2_regexSanitize: function (regexString) {
+        var escapePattern = /([^\\]|^)(%)/g, percentPattern = /\\%/g;
+        return regexString.replace("^", "\\^")
+                .replace("$", "\\$")
+                .replace("(", "\\(")
+                .replace(")", "\\)")
+                .replace("<", "\\<")
+                .replace("[", "\\[")
+                .replace("{", "\\{")
+                .replace(/\\([^%])/, "\\\\$1")    /* don't replace \\% */
+                .replace("|", "\\|")
+                .replace(">", "\\>")
+                .replace(".", "\\.")
+                .replace("*", "\\*")
+                .replace("+", "\\+")
+                .replace("?", "\\?")
+                .replace(escapePattern, "$1.*")  /* replace % with .* */
+                .replace(percentPattern, "%");   /* strip excape of % */ 
+    }, 
+
+    isValidDate: function (d) {
+        if (Object.prototype.toString.call(d) !== "[object Date]")
+            return false;
+        return !isNaN(d.getTime());
+    },
+
+    isValidArray: function (a) {
+        return (Object.prototype.toString.call(a) === "[object Array]");
+    },
+    
+    matchOptionArrayString: function (src, attr, pattern) {
+        /* src.obj[attr] is a StringArray */
+        var _pattern, re, _stringMatch;
+        _pattern = this._wac2_regexSanitize(pattern); 
+        re = new RegExp("^" + _pattern + "$", "i");
+
+        _stringMatch = function (obj, index) {
+            if (pattern.search(/^%*$/i) === 0) 
+                return true;
+            if (obj[attr] === undefined || obj[attr] === null)
+                return false;
+            return obj[attr].some(function (f) {
+                return f.search(re) !== -1;
+            });
+        };
+        return utils.filter(src, _stringMatch);
+    },
+
+    matchOptionString: function (src, attr, pattern) {
+        /* src.obj[attr] is a string */
+        var _stringMatch, _pattern, _re;
+        _pattern = this._wac2_regexSanitize(pattern); 
+        _re = new RegExp("^" + _pattern + "$", "mi");
+
+        _stringMatch = function (obj, index) {
+            return (obj[attr].search(_re) !== -1);
+        };
+        return utils.filter(src, _stringMatch);
+    },
+
+    matchOptionDate: function (src, attr, filterStart, filterEnd) {
+        var _dateMatch;
+        _dateMatch = function (obj, index) {
+            var matched = true, valueDate = obj[attr];
+    
+            if (filterStart !== undefined && filterStart !== null) {
+                matched = (valueDate.getTime() >= filterStart.getTime());
+            }
+            if (matched && (filterEnd !== undefined && filterEnd !== null)) {
+                matched = (valueDate.getTime() <= filterEnd.getTime());
+            }
+            return matched;
+        };
+        return utils.filter(src, _dateMatch);
+    },
+
+    matchOptionShortArray: function (src, attr, filterArray) {
+        /* src.obj[attr] is a short, filterArray is an array 
+           i.e. find status is [CONFRIMED or TENTATIVE] */
+        var arraySome = function (obj, index) {
+            return filterArray.some(function (f) {
+                return f === obj[attr];  
+            });
+        };
+        return utils.filter(src, arraySome);
+    },
+
+    validateTypeMismatch: function (onSuccess, onError, name, callback) {
+        if (onSuccess) {
+            utils.validateArgumentType(onSuccess, "function", null,
+                                       name + " invalid successCallback parameter",
+                                       new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+        }
+
+        if (onError) {
+            utils.validateArgumentType(onError, "function", null,
+                                       name + " invalid errorCallback parameter",
+                                       new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
+        }
+
+        if (onSuccess) {
+            return callback && callback();
+        } else {
+            if (onError) {
+                setTimeout(function () {
+                    onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                }, 1);
+            }
+        }
+        return undefined;
+    },
+
+    isEmptyObject: function (obj) {
+        var prop;
+
+        for (prop in obj) {
+            return false;
+        }
+        return true;
+    }
+};
+
+
+});
+require.define('ripple/platform/wac/2.0/dbfs', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* We know the dbfs is not an accurate simulation of WAC 2.0 filesystem.
+ *
+ * 1) We have tried W3C File API, as some of WAC filesystem APIs are synchronous, 
+ * it is impossible to simulate them by using the asynchronous API in the main
+ * UI thread and although we could use synchronous W3C API in a worker, it is
+ * not reasonable to limit WAC filesystem API usage in a worker.
+ *
+ * 2) The problem is partially solved by using database to simulate the filesystem,
+ * For the asynchronous aspect, actually all the files are read into memory (cache 
+ * object in this file) and the cache operation is synchronous. It is not perfect.
+ * And the database has 5MB limitation when running in Chrome.
+ *
+ * In the future, we might use ajax or NPAPI to get a better simulation.
+ */
+
+/* Note: The entry object is shared between this module and filesystem */
+
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    _console = require('ripple/console'),
+    _cache = {},
+    _self;
+
+function _get(path) {
+    return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
+        return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
+    }, _cache);
+}
+
+function _getInfo(path) {
+    var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
+        name = parent.splice(parent.length - 1, 1).join("");
+
+    return {
+        name: name,
+        parent: parent.join("/") || "/"
+    };
+}
+
+function _set(path, obj) {
+    var parent = _cache,
+        tokens = path.replace(/^\//, '').split("/"),
+        child = tokens.splice(tokens.length - 1, 1).join("");
+
+    tokens.forEach(function (token) {
+        parent = parent.children[token];
+    });
+
+    parent.children = parent.children || {};
+    parent.children[child] = obj;
+}
+
+function _delete(path) {
+    var parent = _cache,
+        tokens = path.replace(/^\//, '').split("/"),
+        child = tokens.splice(tokens.length - 1, 1).join("");
+
+    tokens.forEach(function (token) {
+        parent = parent.children[token];
+    });
+
+    delete parent.children[child];
+}
+
+function _save() {
+    db.saveObject("wac2-db-filesystem", _cache);
+}
+
+function _walk(path, parent) { 
+    _self.ls(path, function (entries) { 
+        parent.children = parent.children || {}; 
+
+        entries.forEach(function (entry) { 
+            parent.children[entry.name] = entry; 
+
+            if (entry.isDirectory) { 
+                _walk(entry.fullPath, entry); 
+            } else { 
+                /* after getting Date out of DB, Date will become 
+                   a string, so need to recast it back to Date */
+                if (entry.lastModifiedDate !== null && entry.lastModifiedDate !== undefined)
+                    entry.lastModifiedDate = new Date(entry.lastModifiedDate);
+
+                _self.read(entry.fullPath, function (data) { 
+                    parent.children[entry.name].data = data; 
+                }, function (e) { 
+                    _console.error(e); 
+                }); 
+            } 
+        }); 
+    }, function (e) { 
+        _console.error(e); 
+    }); 
+} 
+function _createPath(path) { 
+    var parts = path.replace(/^\//, '').split("/"), 
+        workflow = jWorkflow.order(); 
+    parts.forEach(function (part, index) { 
+        var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/"); 
+        workflow.andThen(function (prev, baton) { 
+            baton.take(); 
+            _self.mkdir(dir, baton.pass, baton.pass); 
+        }); 
+    }); 
+    workflow.start(); 
+}
+
+_self = {
+    // The order is consistent with _virtualRoots in filesystem.js
+    roots: ["/opt/documents", "/opt/images", "/opt/music", "/opt/videos", "/opt/downloads", "/home/user/appdata/simulatedapp/wgt-package", "/home/user/appdata/simulatedapp/wgt-private", "/home/user/appdata/simulatedapp/wgt-private-tmp", "/SDCard", "/opt/attachments"],
+    initialize: function () {
+        // TODO: Initialize at bootstrap and emulatorBridge.link 
+        _cache = db.retrieveObject("wac2-db-filesystem") || {};
+        // create real root paths if empty
+        _self.roots.every(function (root) {
+            _createPath(root);
+            return true;
+        }); 
+       // build the file system cache so that we could access information synchronously
+        _walk("/", _cache);
+    },
+    ls: function (path, success, error) {
+        try {
+            var dir = _get(path),
+                items = [];
+
+            if (dir) {
+                utils.forEach(dir.children, function (item) {
+                    items.push(item);
+                });
+            }
+            else {
+                items = {};
+            }
+
+            success(items);
+        }
+        catch (e) {
+            e.code = 1;
+            error(e);
+        }
+    },
+    rm: function (path, success, error, options) {
+        _delete(path);
+        _save();
+        success();
+    },
+    rmdir: function (path, success, error, options) {
+        _delete(path);
+        _save();
+        success();
+    },
+    mkdir: function (path, success, error) {
+        var entry = _get(path),
+            info = _getInfo(path);
+
+        if (!entry) {
+            _set(path, {
+                name: info.name,
+                isDirectory: true,
+                fullPath: path
+            });
+            entry = _get(path);
+            _save();
+        }
+        
+        if (entry) {
+            success(entry);
+        }
+        else {
+            error({code: 1});
+        }
+    },
+    mv: function (from, to, success, error) {
+        try {
+            var fromEntry = _get(from),
+                toInfo = _getInfo(to);
+
+            fromEntry.fullPath = to;
+            fromEntry.name = toInfo.name;
+
+            _set(to, fromEntry);
+            _delete(from);
+            _save();
+            success();
+        }
+        catch (e) {
+            e.code = 1;
+            error(e);
+        }
+    },
+    touch: function (path, success, error) {
+        var entry = _get(path),
+            info  = _getInfo(path);
+
+        if (!entry) {
+            _set(path, {
+                lastModifiedDate: new Date(),
+                name: info.name,
+                isDirectory: false,
+                fullPath: path,
+                data: ""
+            });
+            entry = _get(path);
+        }
+        _save();
+        success(entry);
+    },
+    cp: function (from, to, success, error) {
+        try {
+            var fromEntry = _get(from),
+                copied = utils.copy(fromEntry);
+
+            copied.name  = _getInfo(to).name;
+            copied.fullPath = to;
+            _set(to, copied);
+            _save();
+            success();
+        }
+        catch (e) {
+            e.code = 1;
+            error(e);
+        }
+    },
+    stat: function (path, success, error) {
+        var entry = _get(path);
+        
+        if (entry) {
+            success(entry);
+        } else {
+            error({code: 1});
+        }
+    },
+    write: function (path, contents, success, error, options) {
+        var entry = _get(path);
+
+        if (entry) {
+            entry.lastModifiedDate = new Date();
+            entry.data = contents;
+            _save();
+            success();
+        } else {
+            error({code: 1});
+        }
+
+    },
+    read: function (path, success, error) {
+        var entry = _get(path);
+
+        if (entry) {
+            success(utils.copy(entry.data));
+        }
+        else {
+            error({code: 1});
+        }
+    }
+};
+
+module.exports = _self;
+
+
+});
+require.define('ripple/platform/wac/2.0/deviceinteraction', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var notifications = require('ripple/notifications'),
+    constants = require('ripple/constants'),
+    PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
+    PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
+    DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
+    errorcode = require('ripple/platform/wac/2.0/errorcode'),
+    utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    deviceSettings = require('ripple/deviceSettings'),
+    wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
+    _self,
+    NOTIFY_DURATION_LIMIT = 5000;
+
+function pendingOperation(f) {
+    var _FAKEWAITTIME = 0,
+        pendingObj;
+    
+    if (_FAKEWAITTIME === 0) {
+        f();
+        return undefined;
+    }
+    else {
+        pendingObj = new PendingObject();
+        pendingObj.pendingID = setTimeout(function () {
+            pendingObj.setCancelFlag(false);
+            f();
+        }, _FAKEWAITTIME);
+        return new PendingOperation(pendingObj);
+    }
+}
+
+function checkDuration(duration) {
+    if (duration) {
+        duration = duration | 0;  
+        if (duration <= 0 || duration > NOTIFY_DURATION_LIMIT) {
+            return NOTIFY_DURATION_LIMIT;
+        } else {
+            return duration;
+        }
+    } else {
+        return NOTIFY_DURATION_LIMIT;
+    }
+}
+
+function isMute() {
+    return deviceSettings.retrieve("Config.soundVolume") <= 0;
+}
+
+function isInVibrateMode() {
+    return deviceSettings.retrieve("Config.vibratingMode");
+}
+
+function isBacklightOn() {
+    return deviceSettings.retrieve("Config.backlight");
+}
+
+var vibrator = (function () {
+    var isVibrating = false,
+        terminateAfterPattern = false,
+        pattern = null,
+        pulseIndex = 0,
+        vibrateTimeout = null,
+        terminateTimeout = null,
+        MILLILSECONDS_OF_ONE_VIBRATION = 100,
+        node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
+        movementIndex = 0,
+        movement = [{ left: -10 }, { left: 0 }, { left: 10 }, { left: 0 },
+             {top: -10 }, { top: 0 }, {top: 10 }, { top: 0 }];
+
+    function _clearTimeout() {
+        if (vibrateTimeout) {
+            clearInterval(vibrateTimeout);
+            vibrateTimeout = null;        
+        }
+        if (terminateTimeout) {
+            clearTimeout(terminateTimeout);
+            terminateTimeout = null;        
+        }
+    }  
+    
+    function stopVibrate() {
+        isVibrating = false;
+        _clearTimeout();
+        node.css({left: 0, top: 0}, MILLILSECONDS_OF_ONE_VIBRATION);
+    }
+    
+    function vibrate() {
+        //node.animate(movement[movementIndex], MILLILSECONDS_OF_ONE_VIBRATION);
+        node.css(movement[movementIndex]);
+        movementIndex = (movementIndex + 1) % 8;
+    }
+    
+    function changePulse() {
+        //pattern != null
+        var pulse = pattern[pulseIndex];
+        if (pulse === '.') vibrate();
+        ++pulseIndex;
+        if (pulseIndex >= pattern.length) {
+            if (terminateAfterPattern) {
+                setTimeout(stopVibrate, 1);
+                return;
+            }
+            pulseIndex = 0;
+        }
+    }
+    
+    function terminateVibrate() {
+        terminateAfterPattern = true;
+        terminateTimeout = null;
+        if (pattern === null) {
+            stopVibrate();        
+        }
+    }  
+  
+    function startVibrate(duration, _pattern) {
+        if (!isInVibrateMode()) return;
+        _clearTimeout();
+        terminateAfterPattern = false;
+        movementIndex = 0;
+        
+        if (_pattern) {
+            pattern = _pattern;
+            pulseIndex = 0;
+            vibrateTimeout = setInterval(changePulse, MILLILSECONDS_OF_ONE_VIBRATION);
+            if (duration) 
+                terminateAfterPattern = false;
+            else 
+                terminateAfterPattern = true;
+        } else {
+            pattern = null;
+            vibrateTimeout = setInterval(vibrate, MILLILSECONDS_OF_ONE_VIBRATION);
+        }
+        terminateTimeout = setTimeout(terminateVibrate, checkDuration(duration));        
+        isVibrating = true;
+    }
+
+    event.on("VibratingModeChanged", function (value) {
+        if (value === false) {
+            stopVibrate();
+        }
+    });
+
+    return {
+        startVibrate: startVibrate,
+        stopVibrate: stopVibrate
+    };
+}()); //jslint style
+
+var backlight = (function () {
+    var timeout = null,
+        isNotifying = false,
+        node = jQuery("#" + constants.COMMON.VIEWPORT_CONTAINER);
+        
+    function _clearTimeout() {
+        if (timeout) {
+            clearTimeout(timeout); 
+            timeout = null;
+        }
+    }
+    
+    function _switch(on) {
+        node.css('opacity', on ? '':'0.4');
+    }
+    
+    function switchOff() {
+        if (!isNotifying) return;
+        _clearTimeout();
+        _switch(false);
+        isNotifying = false;
+    }
+    
+    function switchOn(duration) {
+        if (isBacklightOn()) return;
+        _clearTimeout();
+        _switch(true);
+        timeout = setTimeout(switchOff, checkDuration(duration));
+        isNotifying = true;
+    }
+
+    _switch(isBacklightOn());
+    event.on("BacklightChanged", function (value) {
+        _clearTimeout();
+        isNotifying = false;
+        _switch(value);
+    });
+
+    return {
+        switchOn  : switchOn,
+        switchOff : switchOff
+    };
+}()); //jslint style
+
+var beeper = (function () {
+    var isBeeping = false,
+        timeout = null,
+        beepFile = "beep.wav", //TODO: license issues
+        errorHandler = null,
+        _beeper = utils.createElement("audio", {"id": "notify-beeper"});
+        
+    document.getElementById("ui").appendChild(_beeper);
+    _beeper.setAttribute("src", beepFile);
+    _beeper.setAttribute("loop", "true");
+    _beeper.load();
+    
+    function _clearTimeout() {
+        if (timeout) {
+            clearTimeout(timeout);
+            timeout = false;
+        }
+    }
+    
+    function raiseError() {
+        if (errorHandler) {
+            setTimeout(function () {
+                errorHandler(new DeviceApiError(errorcode.UNKNOWN_ERR));
+            }, 1);
+        }
+    }
+    
+    function stopBeep() {
+        _clearTimeout();
+        if (isBeeping) {
+            try {
+                _beeper.pause();
+            } catch (e) {}
+            isBeeping = false;
+        }
+    }
+    
+    _beeper.addEventListener('error', function () {
+        stopBeep();
+        raiseError();
+    });
+   
+    function startBeep(onSuccess, onError, duration) {
+        errorHandler = onError;
+        try {
+            stopBeep();
+            _beeper.currentTime = 0;
+            _beeper.play();
+            isBeeping = true;
+            timeout = setTimeout(stopBeep, checkDuration(duration));
+            setTimeout(function () {
+                onSuccess();
+            }, 1);
+        }catch (e) {
+            raiseError();
+        }
+    }
+    
+    event.on("VolumeChanged", function (value) {
+        value = value | 0;
+        if (value < 0) value = 0;
+        else if (value > 100) value = 100;       
+        _beeper.volume = value / 100.0;
+    });
+    
+    return {
+        startBeep : startBeep,
+        stopBeep  : stopBeep
+    };
+}()); //jslint style
+
+module.exports = _self = {
+
+    startNotify : function (onSuccess, onError, duration) {
+        return wac2_utils.validateTypeMismatch(onSuccess, onError, "startNotify", function () {
+            if (!isMute()) {
+                return pendingOperation(function () {
+                    beeper.startBeep(onSuccess, onError, duration);
+                });
+            } else if (isInVibrateMode()) {
+                return _self.startVibrate(onSuccess, onError, duration);
+            } else {
+                return _self.lightOn(onSuccess, onError, duration);
+            }
+        });
+    },
+
+    stopNotify : function () {
+        beeper.stopBeep();
+        vibrator.stopVibrate();
+        backlight.switchOff();
+    },
+
+    startVibrate : function (onSuccess, onError, duration, pattern) {       
+        return wac2_utils.validateTypeMismatch(onSuccess, onError, "startVibrate", function () {
+            if (pattern) {
+                pattern = String(pattern);
+                if (!pattern.match(/[\._]{1,10}/)) {
+                    if (onError) {
+                        setTimeout(function () {
+                            onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
+                        }, 1);
+                    }
+                    return undefined;
+                }   
+            }
+            
+            if (!isInVibrateMode()) {
+                if (onError) {
+                    setTimeout(function () {
+                        onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
+                    }, 1);
+                }
+                return undefined;          
+            }
+  
+            setTimeout(function () {
+                onSuccess();
+            }, 1);
+            return pendingOperation(function () {
+                vibrator.startVibrate(duration, pattern);
+            });
+
+        });
+    },
+    
+    stopVibrate : function () {
+        vibrator.stopVibrate();
+    },
+
+    lightOn : function (onSuccess, onError, duration) {
+        return wac2_utils.validateTypeMismatch(onSuccess, onError, "lightOn", function () {
+            if (isBacklightOn()) {
+                if (onError) {
+                    setTimeout(function () {
+                        onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
+                    }, 1);
+                }
+                return undefined;               
+            }
+        
+            setTimeout(function () {
+                onSuccess();
+            }, 1);
+            return pendingOperation(function () {
+                backlight.switchOn(duration);
+            });
+        });
+    },
+
+    lightOff : function () {
+        backlight.switchOff();
+    },
+
+    setWallpaper : function (onSuccess, onError, fileName) {
+        //TODO: file name, existance, extension checking.
+        return wac2_utils.validateTypeMismatch(onSuccess, onError, "setWallpaper", function () {
+            return pendingOperation(function () {
+                notifications.openNotification("normal", "setWallpaper:" + fileName);
+                setTimeout(function () {
+                    onSuccess();
+                }, 1);
+            });
+        });
+    }
+};
+
+
+});
+require.define('ripple/platform/wac/2.0/spec/device', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event');
+
+function deviceStatusEventTrigger(setting) {
+    event.trigger("DeviceStatusChanged", [setting]);
+}
+
+module.exports = {
+    "Config": {
+        "vibratingMode": {
+            "name": "Vibrator",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "callback": function (setting) {
+                event.trigger("VibratingModeChanged", [setting]);
+            }
+        },
+        "soundVolume": {
+            "name": "Sound Volume",
+            "control": {
+                "type": "range",
+                "value": 100,
+                "min": 0,
+                "max": 100
+            },
+            "callback": function (setting) {
+                event.trigger("VolumeChanged", [setting]);
+            }
+        },
+        "backlight": {
+            "name": "Backlight",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "callback": function (setting) {
+                event.trigger("BacklightChanged", [setting]);
+            }
+        }
+    },
+    "Battery": {
+        "batteryLevel": {
+            "name": "Battery Remaining %",
+            "control": {
+                "type": "select",
+                "value": 100
+            },
+            "options": (function () {
+                var i,
+                    optionList = {};
+
+                for (i = 0; i <= 100; i += 10) {
+                    optionList[i] = i;
+                }
+
+                return optionList;
+            }()),
+            "event": "BatteryLevelChanged",
+            "callback": function (setting) {
+                event.trigger("BatteryLevelChanged", [setting]);
+            }
+        },
+
+        "batteryBeingCharged": {
+            "name": "Battery Is Charging",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "event": "BatteryBeingChargedChanged",
+            "callback": function (setting) {
+                event.trigger("BatteryBeingChargedChanged", [setting]);
+            }
+        },
+    },
+    "CellularHardware": {
+        "status": {
+            "name": "status",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "event": "CellularHardwareStatusChanged",
+            "callback": function (setting) {
+                event.trigger("CellularHardwareStatusChanged", [setting]);
+            }
+        }
+    },
+    "CellularNetwork": {
+        "isInRoaming": {
+            "name": "Roaming",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "event": "CellularNetworkIsInRoamingChanged",
+            "callback": function (setting) {
+                event.trigger("CellularNetworkIsInRoamingChanged", [setting]);
+            }
+        }, 
+        "mcc": {
+            "name": "mcc",
+            "control": {
+                "type": "text",
+                "value": "460",
+                "readonly": "readonly"
+            }
+        }, 
+        "mnc": {
+            "name": "mnc",
+            "control": {
+                "type": "text",
+                "value": "0",
+                "readonly": "readonly"
+            }
+        }, 
+        "signalStrength": {
+            "name": "Signal Strength",
+            "control": {
+                "type": "select",
+                "value": 100
+            },
+            "options": (function () {
+                var i,
+                    optionList = {};
+
+                for (i = 0; i <= 100; i += 10) {
+                    optionList[i] = i;
+                }
+
+                return optionList;
+            }()),
+            "event": "CellularNetworkSignalStrengthChanged",
+            "callback": function (setting) {
+                event.trigger("CellularNetworkSignalStrengthChanged", [setting]);
+            }
+        }, 
+        "operatorName": {
+            "name": "Operator Name",
+            "control": {
+                "type": "text",
+                "value": "CMCC",
+                "readonly": "readonly"
+            }
+        }
+    },
+    "Device": {
+        "imei": {
+            "name": "IMEI",
+            "control": {
+                "type": "text",
+                "value": "860398001689659",
+                "readonly": "readonly"
+            }
+        }, 
+        "model": {
+            "name": "Model",
+            "control": {
+                "type": "text",
+                "value": "",
+                "readonly": "readonly"
+            }
+        }, 
+        "version": {
+            "name": "Version",
+            "control": {
+                "type": "text",
+                "value": "",
+                "readonly": "readonly"
+            }
+        }, 
+        "vendor": {
+            "name": "Vendor.",
+            "control": {
+                "type": "text",
+                "value": "",
+                "readonly": "readonly"
+            }
+        }
+    },
+    "Display": {
+        "resolutionHeight": {
+            "name": "Resolution Height",
+            "control": {
+                "type": "number",
+                "value": 0,
+                "readonly": "readonly"
+            }
+        }, 
+        "resolutionWidth": {
+            "name": "Resolution Width",
+            "control": {
+                "type": "number",
+                "value": 0,
+                "readonly": "readonly"
+            }
+        }, 
+        "pixelAspectRatio": {
+            "name": "Pixel Aspectratio",
+            "control": {
+                "type": "number",
+                "value": 0,
+                "readonly": "readonly"
+            }
+        }, 
+        "dpiY": {
+            "name": "DPI-Y",
+            "control": {
+                "type": "number",
+                "value": 0,
+                "readonly": "readonly"
+            }
+        },         
+        "dpiX": {
+            "name": "DPI-X",
+            "control": {
+                "type": "number",
+                "value": 0,
+                "readonly": "readonly"
+            }
+        }, 
+        "colorDepth": {
+            "name": "Color Depth",
+            "control": {
+                "type": "number",
+                "value": 32,
+                "readonly": "readonly"
+            }
+        }
+    },
+    "MemoryUnit": {
+        "removable": {
+            "name": "Removable",
+            "control": {
+                "type": "checkbox",
+                "value": true,
+                "readonly": "readonly"
+            }
+        },
+        "size": {
+            "name": "Total Memory",
+            "control": {
+                "type": "number",
+                "value": 262144,
+                "readonly": "readonly"
+            }
+        },        
+        "availableSize": {
+            "name": "Available Size",
+            "control": {
+                "type": "range",
+                "value": 16384,
+                "min": 0,
+                "max": 262144
+            },
+            "event": "MemoryUnitAvailableSizeChanged",
+            "callback": function (setting) {
+                event.trigger("MemoryUnitAvailableSizeChanged", [setting]);
+            }
+        }
+    },
+    "OperatingSystem": {
+        "language": {
+            "name": "Language",
+            "control": {
+                "type": "text",
+                "value": "English",
+                "readonly": "readonly"
+            }
+        }, 
+        "version": {
+            "name": "Version",
+            "control": {
+                "type": "text",
+                "value": "",
+                "readonly": "readonly"
+            }
+        }, 
+        "name": {
+            "name": "Name",
+            "control": {
+                "type": "text",
+                "value": "",
+                "readonly": "readonly"
+            }
+        }, 
+        "vendor": {
+            "name": "Vendor",
+            "control": {
+                "type": "text",
+                "value": "",
+                "readonly": "readonly"
+            }
+        }
+    },
+    "WebRuntime": {
+        "wacVersion": {
+            "name": "WAC Version",
+            "control": {
+                "type": "text",
+                "value": "2.0",
+                "readonly": "readonly"
+            }
+        }, 
+        "supportedImageFormats": {
+            "name": "Image Formats",
+            "control": {
+                "type": "text",
+                "value": "gif87, gif89, png, jpeg",
+                "readonly": "readonly"
+            },
+            "event": "WebRuntimeSupportedImageFormatsChanged",
+            "callback": function (setting) {
+                event.trigger("WebRuntimeSupportedImageFormatsChanged", [setting]);
+            }
+        }, 
+        "version": {
+            "name": "Web Runtime Version",
+            "control": {
+                "type": "text",
+                "value": "1.0",
+                "readonly": "readonly"
+            }
+        }, 
+        "name": {
+            "name": "Web Runtime Name",
+            "control": {
+                "type": "text",
+                "value": "Tizen Web Simulator",
+                "readonly": "readonly"
+            }
+        }, 
+        "vendor": {
+            "name": "Vendor Name",
+            "control": {
+                "type": "text",
+                "value": "Tizen SDK team",
+                "readonly": "readonly"
+            }
+        }
+    },
+    "WiFiHardware": {
+        "status": {
+            "name": "Status",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "event": "WiFiHardwareStatusChanged",
+            "callback": function (setting) {
+                event.trigger("WiFiHardwareStatusChanged", [setting]);
+            }
+        }
+    },
+    "WiFiNetwork": {
+        "ssid": {
+            "name": "SSID",
+            "control": {
+                "type": "text",
+                "value": "OfficeWLAN"
+            },
+            "event": "WiFiHardwareSsidChanged",
+            "callback": function (setting) {
+                event.trigger("WiFiHardwareSsidChanged", [setting]);
+            }
+        }, 
+        "signalStrength": {
+            "name": "Signal Strength",
+            "control": {
+                "type": "select",
+                "value": 10
+            },
+            "options": (function () {
+                var i,
+                    optionList = {};
+
+                for (i = 0; i <= 10; i++) {
+                    optionList[i] = i;
+                }
+
+                return optionList;
+            }()),
+            "event": "WiFiHardwareSignalStrengthChanged",
+            "callback": function (setting) {
+                event.trigger("WiFiHardwareSignalStrengthChanged", [setting]);
+            }
+        }, 
+        "networkStatus": {
+            "name": "Network Status",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "event": "WiFiHardwareNetworkStatusChanged",
+            "callback": function (setting) {
+                event.trigger("WiFiHardwareNetworkStatusChanged", [setting]);
+            }
+        }
+    }
+};
+
+
+});
+require.define('ripple/platform/wac/2.0/spec/ui', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    plugins: [
+        "accelerometer",
+        "messaging",
+        "geoView",
+        "widgetConfig",
+        "deviceSettings"
+    ]
+};
+
+});
+require.define('ripple/platform/wac/2.0/spec/config', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var platform = require('ripple/platform'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    constants = require('ripple/constants');
+
+module.exports = {
+    fileName: "config.xml",
+    validateVersion: function (configValidationObject) {
+        var valid = true;
+        // no xmlns:JIL in wac 2.0 spec
+        valid = !!configValidationObject.widget.validationResult[0].attributes.xmlns.valid;
+
+        return valid;
+    },
+    extractInfo: function (configValidationObject) {
+        if (!configValidationObject) {
+            return null;
+        }
+
+        var widgetInfo = {},
+            configFeatures,
+            configPreferences,
+            preferenceName,
+            platform;
+
+        widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
+        widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
+        widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
+        widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
+
+        widgetInfo.features = {};
+
+        configFeatures = configValidationObject.widget.children.feature.validationResult;
+        utils.forEach(configFeatures, function (f) {
+            if (f.valid === true) {
+                var feature = {id: f.attributes.name.value,
+                         required: f.attributes.required.valid};
+                widgetInfo.features[feature.id] = feature;
+            }
+        });
+
+        widgetInfo.preferences = {};
+
+        configPreferences = configValidationObject.widget.children.preference.validationResult;
+
+        platform = require('ripple/platform');
+        utils.forEach(configPreferences, function (preference) {
+            preferenceName = preference.attributes.name.value;
+            if (preferenceName) {
+                widgetInfo.preferences[preferenceName] = {
+                    "key": preferenceName,
+                    "value": preference.attributes.value.value || "",
+                    "readonly": preference.attributes.readonly.value === "true"
+                };
+
+                db.save(preferenceName,
+                        widgetInfo.preferences[preferenceName].value,
+                        platform.getPersistencePrefix(widgetInfo.id));
+            }
+        });
+
+        return widgetInfo;
+    },
+    schema: {
+        rootElement: "widget",
+        widget: {
+            nodeName: "widget",
+            required: true,
+            occurrence: 1,
+            helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in configuration document and may have following child elments: name,description,icon,author,license,content,feature and preference. \"widget\" element MAY have following attributes: id,version,height,width, defaultlocale, xml:lang and dir",
+            attributes: {
+                xmlns: {
+                    attributeName: "xmlns",
+                    required: true,
+                    type: "list",
+                    listValues: ["http://www.w3.org/ns/widgets"]
+                },
+                "xml:lang": {
+                    attributeName: "xml:lang",
+                    required: false,
+                    type: "iso-language"
+                },
+                dir: {
+                    attributeName: "dir",
+                    required: false,
+                    type: "list",
+                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                },
+                id: {
+                    attributeName: "id",
+                    required: false,
+                    type: "string"
+                },
+                version: {
+                    attributeName: "version",
+                    required: false,
+                    type: "string"
+                },
+                height: {
+                    attributeName: "height",
+                    required: false,
+                    type: "integer"
+                },
+                width: {
+                    attributeName: "width",
+                    required: false,
+                    type: "integer"
+                },
+                viewmodes: {
+                    attributeName: "viewmodes",
+                    required: false,
+                    type: "list",
+                    listValues: ["windowed", "floating", "fullscreen", "maximized", "minimized"]
+                },
+                defaultlocale: {
+                    attributeName: "defaultlocale",
+                    required: false,
+                    type: "iso-language"
+                },
+            },
+            children: {
+                name: {
+                    nodeName: "name",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                            unique: true
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        "short": {
+                            attributeName: "short",
+                            required: false,
+                            type: "string"
+                        }
+                    },
+                    children: {
+                        span: {
+                            nodeName: "span",
+                            required: false,
+                            type: "string",
+                            attributes: {
+                                "xml:lang": {
+                                    attributeName: "xml:lang",
+                                    required: false,
+                                    type: "iso-language",
+                                    unique: true
+                                },
+                                dir: {
+                                    attributeName: "dir",
+                                    required: false,
+                                    type: "list",
+                                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                                }
+                            }
+                        }
+                    }
+                },
+                description: {
+                    nodeName: "description",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                            unique: true
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        }
+                    },
+                    children: {
+                        span: {
+                            nodeName: "span",
+                            required: false,
+                            type: "string",
+                            attributes: {
+                                "xml:lang": {
+                                    attributeName: "xml:lang",
+                                    required: false,
+                                    type: "iso-language",
+                                    unique: true
+                                },
+                                dir: {
+                                    attributeName: "dir",
+                                    required: false,
+                                    type: "list",
+                                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                                }
+                            }
+                        }
+                    }
+                },
+                author: {
+                    nodeName: "author",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        href: {
+                            attributeName: "href",
+                            required: false,
+                            type: "regex",
+                            regex: constants.REGEX.URL
+                        },
+                        email: {
+                            attributeName: "email",
+                            required: false,
+                            type: "regex",
+                            regex: constants.REGEX.EMAIL
+                        }
+                    },
+                    children: {
+                        span: {
+                            nodeName: "span",
+                            required: false,
+                            type: "string",
+                            attributes: {
+                                "xml:lang": {
+                                    attributeName: "xml:lang",
+                                    required: false,
+                                    type: "iso-language",
+                                    unique: true
+                                },
+                                dir: {
+                                    attributeName: "dir",
+                                    required: false,
+                                    type: "list",
+                                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                                }
+                            }
+                        }
+                    }
+                },
+                license: {
+                    nodeName: "license",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        href: {
+                            attributeName: "href",
+                            type: "regex",
+                            required: false,
+                            regex: constants.REGEX.URL
+                        }
+                    },
+                    children: {
+                        span: {
+                            nodeName: "span",
+                            required: false,
+                            type: "string",
+                            attributes: {
+                                "xml:lang": {
+                                    attributeName: "xml:lang",
+                                    required: false,
+                                    type: "iso-language",
+                                    unique: true
+                                },
+                                dir: {
+                                    attributeName: "dir",
+                                    required: false,
+                                    type: "list",
+                                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                                }
+                            }
+                        }
+                    }
+                },
+                icon: {
+                    nodeName: "icon",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        src: {
+                            attributeName: "src",
+                            required: true,
+                            type: "string"
+                        },
+                        width: {
+                            attributeName: "width",
+                            required: false,
+                            type: "integer"
+                        },
+                        height: {
+                            attributeName: "height",
+                            required: false,
+                            type: "integer"
+                        }
+                    }
+                },
+                content: {
+                    nodeName: "content",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                            unique: true
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        src: {
+                            attributeName: "src",
+                            required: true,
+                            type: "string"
+                        },
+                        encoding: {
+                            attributeName: "encoding",
+                            required: false,
+                            type: "string"
+                        },
+                        type: {
+                            attributeName: "type",
+                            required: false,
+                            type: "string"
+                        }
+                    }
+                },
+                feature: {
+                    nodeName: "feature",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        name: {
+                            attributeName: "name",
+                            required: true,
+                            type: "list",
+                            listValues: ["http://www.w3.org/TR/geolocation-API/",
+                                            "http://wacapps.net/api/deviceapis", "http://wacapps.net/api/accelerometer",
+                                            "http://wacapps.net/api/orientation", "http://wacapps.net/api/camera",
+                                            "http://wacapps.net/api/camera.show", "http://wacapps.net/api/camera.capture",
+                                            "http://wacapps.net/api/devicestatus", "http://wacapps.net/api/devicestatus.deviceinfo",
+                                            "http://wacapps.net/api/devicestatus.networkinfo", "http://wacapps.net/api/filesystem",
+                                            "http://wacapps.net/api/filesystem.read", "http://wacapps.net/api/filesystem.write",
+                                            "http://wacapps.net/api/messaging", "http://wacapps.net/api/messaging.send", 
+                                            "http://wacapps.net/api/messaging.find", "http://wacapps.net/api/messaging.subscribe",
+                                            "http://wacapps.net/api/messaging.write", "http://wacapps.net/api/pim.contact",
+                                            "http://wacapps.net/api/pim.contact.read", "http://wacapps.net/api/pim.contact.write",
+                                            "http://wacapps.net/api/pim.calendar", "http://wacapps.net/api/pim.calendar.read",
+                                            "http://wacapps.net/api/pim.calendar.write", "http://wacapps.net/api/pim.task", 
+                                            "http://wacapps.net/api/pim.task.read", "http://wacapps.net/api/pim.task.write",
+                                            "http://wacapps.net/api/deviceinteraction"]
+                        },
+                        required: {
+                            attributeName: "required",
+                            type: "boolean",
+                            required: false
+                        }
+                    },
+                    children: {
+                        param: {
+                            nodeName: "param",
+                            required: false,
+                            occurrence: 0,
+                            attributes: {
+                                "xml:lang": {
+                                    attributeName: "xml:lang",
+                                    required: false,
+                                    type: "iso-language",
+                                },
+                                dir: {
+                                    attributeName: "dir",
+                                    required: false,
+                                    type: "list",
+                                    listValues: ["ltr", "rtl", "lro", "rlo"]
+                                },
+                                name: {
+                                    attributeName: "name",
+                                    required: true,
+                                    type: "string",
+                                },
+                                value: {
+                                    attributeName: "value",
+                                    required: true,
+                                    type: "string",
+                                }
+                            }
+                        }
+                    }
+                },
+                preference: {
+                    nodeName: "preference",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            required: false,
+                            type: "iso-language",
+                        },
+                        dir: {
+                            attributeName: "dir",
+                            required: false,
+                            type: "list",
+                            listValues: ["ltr", "rtl", "lro", "rlo"]
+                        },
+                        name: {
+                            attributeName: "name",
+                            required: true,
+                            type: "string"
+                        },
+                        value: {
+                            type: "string",
+                            required: false,
+                            attributeName: "value"
+                        },
+                        readonly: {
+                            attributeName: "readonly",
+                            type: "boolean",
+                            required: false
+                        }
+                    }
+                }
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/platform/wac/2.0/spec', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = {
+
+    id: "wac",
+    version: "2.0",
+    name: "WAC",
+
+    persistencePrefix: "wac2-",
+
+    config: require('ripple/platform/wac/2.0/spec/config'),
+    ui: require('ripple/platform/wac/2.0/spec/ui'),
+    device: require('ripple/platform/wac/2.0/spec/device'),
+
+    objects: {
+        Coordinates: {
+            path: "w3c/1.0/Coordinates"
+        },
+        Position: {
+            path: "w3c/1.0/Position"
+        },
+        PositionError: {
+            path: "w3c/1.0/PositionError"
+        },
+        navigator: {
+            path: "w3c/1.0/navigator",
+            children: {
+                geolocation: {
+                    path: "wac/2.0/geolocation",
+                    feature: "http://www.w3.org/TR/geolocation-API/"
+                }
+            }
+        },
+        deviceapis: {
+            path: "wac/2.0/deviceapis",
+            feature: "http://wacapps.net/api/deviceapis",
+            /*
+             * Before we inject those cloned objects into the simulated application
+             * namespace, we will handle the feature requests from config.xml.
+             * Especially for:
+             * - camera.show, camera.capture
+             * - devicestatus.deviceinfo, devicestatus.networkinfo
+             * - filesystem.read, filesystem.write
+             * - messaging.send, messaging.find, messaging.subscribe, messaging.write
+             * - pim
+             *  - contact.read, contact.write
+             *  - calendar.read, calendar.write
+             *  - task.read, task.write
+             */
+            children: {
+                accelerometer: {
+                    path: "wac/2.0/accelerometer",
+                    feature: "http://wacapps.net/api/accelerometer"
+                },
+                orientation: {
+                    path: "wac/2.0/orientation",
+                    feature: "http://wacapps.net/api/orientation"
+                },
+                camera: {
+                    path: "wac/2.0/camera",
+                    feature: "http://wacapps.net/api/camera|http://wacapps.net/api/camera.show|http://wacapps.net/api/camera.capture",
+                    handleSubfeatures: true
+                },
+                devicestatus: {
+                    path: "wac/2.0/devicestatus",
+                    feature: "http://wacapps.net/api/devicestatus|http://wacapps.net/api/devicestatus.deviceinfo|http://wacapps.net/api/devicestatus.networkinfo",
+                    handleSubfeatures: true
+                },
+                filesystem: {
+                    path: "wac/2.0/filesystem",
+                    feature: "http://wacapps.net/api/filesystem|http://wacapps.net/api/filesystem.read|http://wacapps.net/api/filesystem.write",
+                    handleSubfeatures: true
+                },
+                messaging: {
+                    path: "wac/2.0/messaging",
+                    feature: "http://wacapps.net/api/messaging|http://wacapps.net/api/messaging.send|http://wacapps.net/api/messaging.find|http://wacapps.net/api/messaging.subscribe|http://wacapps.net/api/messaging.write",
+                    handleSubfeatures: true
+                },
+                pim: {
+                    children: {
+                        contact: {
+                            path: "wac/2.0/contact",
+                            feature: "http://wacapps.net/api/pim.contact|http://wacapps.net/api/pim.contact.read|http://wacapps.net/api/pim.contact.write",
+                            handleSubfeatures: true
+                        },
+                        calendar: {
+                            path: "wac/2.0/calendar",
+                            feature: "http://wacapps.net/api/pim.calendar.write|http://wacapps.net/api/pim.calendar.read|http://wacapps.net/api/pim.calendar",
+                            handleSubfeatures: true
+                        },
+                        task: {
+                            path: "wac/2.0/task",
+                            feature: "http://wacapps.net/api/pim.task|http://wacapps.net/api/pim.task.read|http://wacapps.net/api/pim.task.write",
+                            handleSubfeatures: true
+                        }
+                    }
+                },
+                deviceinteraction: {
+                    path: "wac/2.0/deviceinteraction",
+                    feature: "http://wacapps.net/api/deviceinteraction"
+                }
+            }
+        }
+    }
+};
+
+
+});
+require.define('ripple/platform/wac/2.0/pendingoperation', function (require, module, exports) {
+/*
+ *  Copyright 2011 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = function (pendingObj) {
+    var pending = true;
+    this.cancel = function () {
+        if (pending === true) {
+            if (typeof (pendingObj.getCancelFlag) === "function" && pendingObj.getCancelFlag() === false) {
+                pending = false;
+                // this clearTimeout is for the case when a 3rd party is invoked to do the task, and it's finished sooner than the intended timeout. therefore, the 3rd party set CancelFlag false, and this cancel is called before timeout
+                clearTimeout(pendingObj.pendingID);
+                return false;
+            }
+            if (typeof (pendingObj.userCancel) === "function") {
+                pendingObj.userCancel();
+            }
+            clearTimeout(pendingObj.pendingID);
+            pending = false;
+            return true;
+        } else {
+            return false;
+        }
+    };
+};
+
+
+});
+require.define('ripple/platform/wac/1.0/PositionInfo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var geo = require('ripple/geo'),
+    event = require('ripple/event'),
+    exception = require('ripple/exception'),
+    utils = require('ripple/utils'),
+    _self = {
+        latitude: undefined,
+        longitude: undefined,
+        altitude: undefined,
+        cellID: undefined,
+        accuracy: undefined,
+        altitudeAccuracy: undefined,
+        timeStamp: undefined
+    };
+
+utils.forEach(_self, function (value, property) {
+    _self.__defineGetter__(property, function () {
+        return geo.getPositionInfo()[property];
+    });
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/MessageTypes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    EmailMessage: "email",
+    MMSMessage: "mms",
+    SMSMessage: "sms"
+};
+
+});
+require.define('ripple/platform/wac/1.0/DataNetworkConnectionTypes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    _self = {
+        "BLUETOOTH": undefined,
+        "EDGE": undefined,
+        "EVDO": undefined,
+        "GPRS": undefined,
+        "IRDA": undefined,
+        "LTE": undefined,
+        "ONEXRTT": undefined,
+        "WIFI": undefined
+    };
+
+utils.forEach(_self, function (value, property) {
+    _self.__defineGetter__(property, function () {
+        return property;
+    });
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/DeviceStateInfo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    _console = require('ripple/console'),
+    geo = require('ripple/geo'),
+    event = require('ripple/event'),
+    deviceSettings = require('ripple/deviceSettings'),
+    PositionInfo = require('ripple/platform/wac/1.0/PositionInfo'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+    _self;
+
+event.on("ScreenChangeDimensions", function (width, height) {
+    try {
+        if (typeof _self.onScreenChangeDimensions === 'function') {
+            _self.onScreenChangeDimensions(width, height);
+        }
+        _console.log("called DeviceStateInfo.onScreenChangeDimensions callback function with width = " + width + " and height = " + height);
+    } catch (e) {
+        exception.handle(e, false);
+    }
+});
+
+_self = {
+    availableMemory: undefined,
+    language: undefined,
+    keypadLightOn: undefined,
+    backLightOn: undefined,
+    processorUtilizationPercent: undefined,
+    audioPath: undefined,
+
+    onPositionRetrieved: undefined,
+
+    requestPositionInfo: function (method) {
+        utils.validateNumberOfArguments(1, 1, arguments.length,
+            ExceptionTypes.INVALID_PARAMETER, "requestPositionInfo invalid number of parameters", new Exception());
+        utils.validateArgumentType(method, "string",
+            ExceptionTypes.INVALID_PARAMETER, "requestPositionInfo invalid parameter", new Exception());
+
+        if (!(method.match(/gps|agps|cellid/))) {
+            exception.raise(ExceptionTypes.INVALID_PARAMETER,
+                    "Invalid method, expected (gps, agps or cellid)", Exception);
+        }
+
+        if (typeof _self.onPositionRetrieved === "function") {
+            var delay = geo.delay * 1000,
+                timeout = geo.timeout;
+            setTimeout(function () {
+                var pos = PositionInfo,
+                    errorObj = {};
+
+                if (timeout) {
+                    //create
+                    utils.forEach(pos, function (val, key) {
+                        errorObj[key] = undefined;
+                    });
+                    pos = errorObj;
+                }
+                _self.onPositionRetrieved(pos, method);
+            }, delay);
+        }
+    },
+
+    onScreenChangeDimensions: undefined,
+
+    onFlipEvent: undefined
+};
+
+_self.__defineGetter__("availableMemory", function () {
+    return deviceSettings.retrieveAsInt("DeviceStateInfo.availableMemory");
+});
+
+_self.__defineGetter__("language", function () {
+    return deviceSettings.retrieve("DeviceStateInfo.language");
+});
+
+_self.__defineGetter__("keypadLightOn", function () {
+    return deviceSettings.retrieveAsBoolean("DeviceStateInfo.keypadLightOn");
+});
+
+_self.__defineGetter__("backLightOn", function () {
+    return deviceSettings.retrieveAsBoolean("DeviceStateInfo.backLightOn");
+});
+
+_self.__defineGetter__("audioPath", function () {
+    return deviceSettings.retrieve("DeviceStateInfo.audioPath");
+});
+
+_self.__defineGetter__("processorUtilizationPercent", function () {
+    return deviceSettings.retrieve("DeviceStateInfo.processorUtilizationPercent");
+});
+
+module.exports = _self;
+
+
+});
+require.define('ripple/platform/wac/1.0/CallRecord', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function () {
+    this.callRecordType = undefined;
+    this.callRecordId = undefined;
+    this.callRecordAddress = undefined;
+    this.callRecordName = undefined;
+    this.durationSeconds = undefined;
+    this.startTime = undefined;
+};
+
+});
+require.define('ripple/platform/wac/1.0/Telephony', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    exception = require('ripple/exception'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    constants = require('ripple/constants'),
+    Device = require('ripple/platform/wac/1.0/Device'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+    Exception = require('ripple/platform/wac/1.0/Exception');
+
+
+function _throwUnsupportedException(method) {
+    exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
+}
+
+_self = {
+
+    // Public Callbacks
+    onCallEvent: undefined,// function (callType, phoneNumber) { },
+    onCallRecordsFound: undefined,// function (callRecords) { };
+
+    // Public Methods
+    initiateVoiceCall: function (phoneNumber) {
+        utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "initiateVoiceCall invalid number of parameters", new Exception());
+        //HACK: should this be hardcoded?
+        //I am still not even sure this is the correct behaviour
+        Device.launchApplication("PHONECALL", phoneNumber);
+
+        if (_self.onCallEvent) {
+            //HACK: shouldn't be hardcoded
+            //also what should the context be? isn't spec'ed
+            _self.onCallEvent.apply(_self, ["outgoing", phoneNumber]);
+        }
+    },
+    getCallRecordCnt: function (callRecordType) {
+        utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "getCallRecordCnt invalid number of parameters", new Exception());
+        var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY);
+
+        return utils.sum(calls, function (call) {
+            return call.callRecordType === callRecordType;
+        });
+    },
+    getCallRecord: function (callRecordType, id) {
+        utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "getCallRecord invalid number of parameters", new Exception());
+        var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY);
+
+        return utils.map(calls, function (call) {
+            return call.callRecordType === callRecordType ? call : null;
+        }).reduce(function (match, call) {
+            return match || call.callRecordId === id || null;
+        }, null);
+    },
+    deleteCallRecord: function (callRecordType, id) {
+        utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "deleteCallRecord invalid number of parameters", new Exception());
+        var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY),
+            indexToDelete = calls.reduce(function (result, call, index) {
+                return call.callRecordType === callRecordType &&
+                       call.callRecordId === id ? index : result;
+            }, -1);
+
+        if (indexToDelete >= 0) {
+            calls.splice(indexToDelete, 1);
+            db.saveObject(constants.TELEPHONY.CALL_LIST_KEY, calls);
+        }
+
+    },
+
+    deleteAllCallRecords: function (callRecordType) {
+        utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "deleteAllCallRecords invalid number of parameters", new Exception());
+        var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY),
+            indexesToDelete = calls.reduce(function (result, call, index) {
+                if (call.callRecordType === callRecordType) {
+                    result.push(index);
+                }
+                return result;
+            }, []);
+
+        utils.forEach(indexesToDelete, function (index) {
+            calls.splice(index, 1);
+        });
+
+        if (indexesToDelete.length > 0) {
+            db.saveObject(constants.TELEPHONY.CALL_LIST_KEY, calls);
+        }
+
+    },
+
+    findCallRecords: function (comparisonRecord, startInx, endInx) {
+        utils.validateNumberOfArguments(1, 3, arguments.length, ExceptionTypes.INVALID_PARAMETER, "findCallRecords invalid number of parameters", new Exception());
+        var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY);
+        utils.find(comparisonRecord, calls, startInx, endInx, _self.onCallRecordsFound);
+
+    }
+
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/AccountInfo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var deviceSettings = require('ripple/deviceSettings'),
+    _self = {
+        phoneUserUniqueId: undefined,
+        phoneMSISDN: undefined,
+        phoneOperatorName: undefined,
+        userAccountBalance: undefined,
+        userSubscriptionType: undefined
+    };
+
+_self.__defineGetter__("phoneUserUniqueId", function () {
+    return deviceSettings.retrieve("AccountInfo.phoneUserUniqueId");
+});
+
+_self.__defineGetter__("phoneMSISDN", function () {
+    return deviceSettings.retrieve("AccountInfo.phoneMSISDN");
+});
+
+_self.__defineGetter__("phoneOperatorName", function () {
+    return deviceSettings.retrieve("AccountInfo.phoneOperatorName");
+});
+
+_self.__defineGetter__("userAccountBalance", function () {
+    return deviceSettings.retrieve("AccountInfo.userAccountBalance");
+});
+
+_self.__defineGetter__("userSubscriptionType", function () {
+    return deviceSettings.retrieve("AccountInfo.userSubscriptionType");
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/CalendarItem', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    db = require('ripple/db'),
+    exception = require('ripple/exception'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes');
+
+module.exports = function () {
+    this.calendarItemId = undefined;
+    this.alarmDate = undefined;
+    this.eventStartTime = undefined;
+    this.eventEndTime = undefined;
+    this.eventName = undefined;
+    this.eventNotes = undefined;
+    this.alarmed = undefined;
+
+    this.update = function () {
+        var events = db.retrieveObject(constants.PIM.CALENDAR_LIST_KEY) || [],
+            that = this,
+            eventIndex = events.reduce(function (match, value, i) {
+                return value.calendarItemId === that.calendarItemId ?
+                    i : match;
+            }, -1);
+
+
+        if (eventIndex >= 0) {
+            events[eventIndex] = this;
+            db.saveObject(constants.PIM.CALENDAR_LIST_KEY, events);
+        }
+        else {
+            exception.raise(ExceptionTypes.INVALID_PARAMETER, "Calendar Item not found: " + (this.calendarItemId || ""), new Exception());
+        }
+    };
+};
+
+});
+require.define('ripple/platform/wac/1.0/AccelerometerInfo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var accelerometer = require('ripple/accelerometer'),
+    _self = {};
+
+_self.__defineGetter__("xAxis", function () {
+    return accelerometer.getInfo().accelerationIncludingGravity.x;
+});
+
+_self.__defineGetter__("yAxis", function () {
+    return accelerometer.getInfo(true).accelerationIncludingGravity.y;
+});
+
+_self.__defineGetter__("zAxis", function () {
+    return accelerometer.getInfo(true).accelerationIncludingGravity.z;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/MessageFolderTypes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    DRAFTS: "drafts",
+    INBOX: "inbox",
+    OUTBOX: "outbox",
+    SENTBOX: "sentbox"
+};
+
+});
+require.define('ripple/platform/wac/1.0/Config', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    notifications = require('ripple/notifications'),
+    constants = require('ripple/constants'),
+    deviceSettings = require('ripple/deviceSettings'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    _self = {
+        ringtoneVolume: undefined,
+        msgRingtoneVolume: undefined,
+        vibrationSetting: undefined,
+
+        setDefaultRingtone: function (ringtoneUrl) {
+            utils.validateArgumentType(ringtoneUrl, "string", ExceptionTypes.INVALID_PARAMETER, "ringtoneUrl paramter is not a string", new Exception());
+            notifications.openNotification("normal", "Setting default ringtone to: " + ringtoneUrl);
+        },
+
+        setAsWallpaper: function (wallpaperUrl) {
+            utils.validateArgumentType(wallpaperUrl, "string", ExceptionTypes.INVALID_PARAMETER, "wallpaperUrl paramter is not a string", new Exception());
+            notifications.openNotification("normal", "Setting wallpaper to: " + wallpaperUrl);
+        }
+    };
+
+_self.__defineGetter__("ringtoneVolume", function () {
+    return deviceSettings.retrieve("Config.ringtoneVolume");
+});
+
+_self.__defineGetter__("msgRingtoneVolume", function () {
+    return deviceSettings.retrieve("Config.msgRingtoneVolume");
+});
+
+_self.__defineGetter__("vibrationSetting", function () {
+    return deviceSettings.retrieve("Config.vibrationSetting");
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/Message', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var exception = require('ripple/exception'),
+    Attachment = require('ripple/platform/wac/1.0/Attachment'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+    Exception = require('ripple/platform/wac/1.0/Exception');
+
+function _throwUnsupportedException(method) {
+    exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
+}
+
+module.exports = function () {
+    this.messageId = Math.uuid(undefined, 16);
+    this.callbackNumber = undefined;
+    this.destinationAddress = [];
+    this.isRead = undefined;
+    this.messagePriority = undefined;
+    this.messageType = undefined;
+    this.subject = undefined;
+    this.body = undefined;
+    this.sourceAddress = undefined;
+    this.validityPeriodHours = undefined;
+    this.time = undefined;
+    this.ccAddress = [];
+    this.bccAddress = [];
+    this.attachments = [];
+
+    this.addAttachment = function (fileFullName) {
+        var attachment = new Attachment();
+        attachment.fileName = fileFullName;
+        this.attachments.push(attachment);
+    };
+    this.deleteAttachment = function (attachment) {
+
+        for (var i = this.attachments.length - 1; i >= 0; i--) {
+            if (this.attachments[i].fileName === attachment.fileName) {
+                this.attachments.splice(i, 1);
+            }
+        }
+    };
+    this.saveAttachment = function (fileFullName, attachment) {
+        _throwUnsupportedException("Widget.Messaging.Message.addAddress");
+    };
+    this.addAddress = function (type, address) {
+
+        var addresses = address.split(";");
+
+        switch (type) {
+        case "destination":
+            this.destinationAddress = this.destinationAddress.concat(addresses);
+            break;
+        case "cc":
+            this.ccAddress = this.ccAddress.concat(addresses);
+            break;
+        case "bcc":
+            this.bccAddress = this.bccAddress.concat(addresses);
+            break;
+        }
+    };
+
+    this.deleteAddress = function (type, address) {
+        var addresses = address.split(";"),
+            filter = function (orig) {
+                return orig.filter(function (address) {
+                    return !addresses.some(function (x) {
+                        return address === x;
+                    });
+                });
+            };
+
+        switch (type) {
+        case "destination":
+            this.destinationAddress = filter(this.destinationAddress);
+            break;
+        case "cc":
+            this.ccAddress = filter(this.ccAddress);
+            break;
+        case "bcc":
+            this.bccAddress = filter(this.bccAddress);
+            break;
+        }
+    };
+
+};
+
+});
+require.define('ripple/platform/wac/1.0/VideoPlayer', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    _console = require('ripple/console'),
+    event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    fileSystem = require('ripple/fileSystem'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    exception = require('ripple/exception'),
+    _currentlySet,
+    _currentVideoFile,
+    _state = null,
+    _loopCount, _video,
+    _STATES = {
+        "OPENED": "opened",
+        "STOPPED": "stopped",
+        "PAUSED": "paused",
+        "PLAYING": "playing",
+        "COMPLETED": "completed"
+    };
+
+function _validateVideoType(fileUrl) {
+    var matched = fileUrl.match(/\.(\w*)$/),
+        maps = {
+            "ogv": "ogg",
+            "flv": "mp4"
+        },
+        type = matched ? matched[1] : "";
+
+    if (_video && _video.canPlayType("video/" + (maps[type] || type)) === "") {
+        _console.warn("Attempting to load a video that might not work in the current browser [" + fileUrl + "]");
+    }
+}
+
+function _validateAndSet(state, validStates, callbackBeforeSuccess) {
+    var i, valid = false;
+
+    for (i = 0; i < validStates.length; i++) {
+        if (validStates[i] === _state) {
+            valid = true;
+        }
+    }
+
+    if (!valid) {
+        _console.warn("Attempted to initiate VideoPlayer." + state +
+            " in invalid state. current state: " + _state);
+    } else {
+        if (typeof(callbackBeforeSuccess) === "function") {
+            callbackBeforeSuccess.apply();
+        }
+        event.trigger("MultimediaVideoStateChanged", [state], true);
+    }
+
+    return valid;
+}
+
+event.on("MultimediaVideoStateChanged", function (state) {
+    _state = state;
+    if (typeof _self.onStateChange === "function") {
+        _self.onStateChange.apply(_self, [state]);
+    }
+});
+
+_self = module.exports = {
+    onStateChange: undefined,
+
+    open: function (fileUrl) {
+        utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER,
+           "VideoPlayer.open invalid number of arguments", new Exception());
+        utils.validateArgumentType(fileUrl, "string", ExceptionTypes.INVALID_PARAMETER,
+           "VideoPlayer.open expected valid fileUrl but got ->" + fileUrl, new Exception());
+
+        if (!_video) {
+            return;
+        }
+
+        _validateAndSet(_STATES.OPENED, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED, null], function () {
+            _validateVideoType(fileUrl);
+            _currentVideoFile = fileSystem.getURI(fileUrl);
+            _video.setAttribute("src", _currentVideoFile);
+            _video.setAttribute("width", "100%");
+            _video.addEventListener("ended", function () {
+                event.trigger("MultimediaVideoStateChanged", [_STATES.COMPLETED], true);
+                if (_loopCount > 1) {
+                    _self.open(_currentVideoFile);
+                    _self.play(_loopCount--);
+                }
+            }, false);
+        });
+    },
+
+    setWindow: function (domObject) {
+        utils.validateNumberOfArguments(0, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER,
+           "VideoPlayer.setWindow invalid number of arguments", new Exception());
+
+        if (_currentlySet) {
+            _currentlySet.removeChild(_video);
+            _currentlySet = null;
+            _video = null;
+        }
+
+        if (domObject !== null) {
+            _video = utils.createElement("video", {
+                "id": "multimedia-video"
+            });
+            domObject.appendChild(_video);
+            _currentlySet = domObject;
+            event.trigger("MultimediaAppVideoPlayerCreated", [_video], true);
+        }
+    },
+
+    play: function (repeatTimes) {
+        utils.validateNumberOfArguments(1, 1, arguments.length,
+            ExceptionTypes.INVALID_PARAMETER, "invalid number of arguments (expected one)", new Exception());
+
+        if (typeof repeatTimes !== "number" || repeatTimes < 0) {
+            exception.raise(ExceptionTypes.INVALID_PARAMETER, "VideoPlayer.play was passed an invalid number of play times: " + repeatTimes, new Exception());
+        }
+        if (repeatTimes !== 0) {
+            if (!_video) {
+                return;
+            }
+            _loopCount = repeatTimes;
+            _validateAndSet(_STATES.PLAYING, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED], function () {
+                _video.play();
+            });
+        }
+    },
+
+    pause: function () {
+        if (!_video) {
+            return;
+        }
+        _validateAndSet(_STATES.PAUSED, [_STATES.PLAYING], function () {
+            _video.pause();
+        });
+    },
+
+    resume: function () {
+        if (!_video) {
+            return;
+        }
+        _validateAndSet(_STATES.PLAYING, [_STATES.PAUSED], function () {
+            _video.play();
+        });
+    },
+
+    stop: function () {
+        if (!_video) {
+            return;
+        }
+        _validateAndSet(_STATES.STOPPED, [_STATES.PAUSED, _STATES.PLAYING], function () {
+            _video.pause();
+            _video.setAttribute("src", _currentVideoFile); // hack
+        });
+    }
+
+};
+
+});
+require.define('ripple/platform/wac/1.0/File', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.expots = function () {
+    this.createDate = undefined;
+    this.fileName = undefined;
+    this.filePath = undefined;
+    this.fileSize = undefined;
+    this.isDirectory = undefined;
+    this.lastModifyDate = undefined;
+};
+
+});
+require.define('ripple/platform/wac/1.0/RadioSignalSourceTypes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    utils = require('ripple/utils');
+
+_self = {
+    "CDMA": undefined,
+    "GSM": undefined,
+    "LTE": undefined,
+    "TDSCDMA": undefined,
+    "WCDMA": undefined
+};
+
+utils.forEach(_self, function (value, property) {
+    _self.__defineGetter__(property, function () {
+        return property;
+    });
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/ExceptionTypes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self =  {};
+
+_self.__defineGetter__("INVALID_PARAMETER", function () {
+    return "invalid_parameter";
+});
+
+_self.__defineGetter__("SECURITY", function () {
+    return "security";
+});
+
+_self.__defineGetter__("UNKNOWN", function () {
+    return "unknown";
+});
+
+_self.__defineGetter__("UNSUPPORTED", function () {
+    return "unsupported";
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/RadioInfo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    event = require('ripple/event'),
+    _console = require('ripple/console'),
+    deviceSettings = require('ripple/deviceSettings');
+
+_self = {
+    isRoaming: undefined,
+    radioSignalStrengthPercent: undefined,
+    isRadioEnabled: undefined,
+    radioSignalSource: undefined,
+    onSignalSourceChange: undefined
+};
+
+event.on("RadioSignalSourceChanged", function () {
+    var callback = _self.onSignalSourceChange,
+        isRoaming = _self.isRoaming,
+        signalSource = _self.radioSignalSource,
+        msg = "Fired onSignalSourceChange. signalSource: " + signalSource + ", isRoaming: " + isRoaming;
+
+    if (callback && typeof callback === "function") {
+        callback.apply(null, [signalSource, isRoaming]);
+    }
+    else {
+        msg += " --> BUT there was no registered callback found.";
+    }
+
+    _console.log(msg);
+});
+
+_self.__defineGetter__("radioSignalSource", function () {
+    return deviceSettings.retrieve("RadioInfo.radioSignalSource");
+});
+
+_self.__defineGetter__("isRoaming", function () {
+    return deviceSettings.retrieveAsBoolean("RadioInfo.isRoaming");
+});
+
+_self.__defineGetter__("isRadioEnabled", function () {
+    return deviceSettings.retrieveAsBoolean("RadioInfo.isRadioEnabled");
+});
+
+_self.__defineGetter__("radioSignalStrengthPercent", function () {
+    return deviceSettings.retrieveAsInt("RadioInfo.radioSignalStrengthPercent");
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/PIM', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    exception = require('ripple/exception'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+    AddressBookItem = require('ripple/platform/wac/1.0/AddressBookItem'),
+    CalendarItem = require('ripple/platform/wac/1.0/CalendarItem'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    constants = require('ripple/constants');
+
+function _throwUnsupportedException(method) {
+    exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
+}
+
+function _toAddressBookItem(contact) {
+    if (!contact) {
+        return null;
+    }
+
+    var addressBookItem = new AddressBookItem();
+
+    utils.forEach(contact, function (prop, key) {
+        addressBookItem[key] = contact[key];
+    });
+
+    return addressBookItem;
+}
+
+function _toCalendarItem(item) {
+    if (!item) {
+        return null;
+    }
+
+    var calendarItem = new CalendarItem();
+
+    utils.forEach(item, function (prop, key) {
+        calendarItem[key] = item[key];
+    });
+
+    return calendarItem;
+}
+
+function _getData(type) {
+    var data = db.retrieveObject(type) || [];
+    return data;
+}
+
+function _saveData(type, items) {
+    db.saveObject(type, items);
+}
+
+function _getContacts() {
+    var contacts = _getData(constants.PIM.ADDRESS_LIST_KEY),
+        gord,
+        dan,
+        brent,
+        pj,
+        mark;
+
+    if (contacts.length === 0) {
+
+        gord = new AddressBookItem();
+        gord.addressBookItemId = "0";
+        gord.fullName = "Gord Tanner";
+        gord.eMail = "gord@tinyHippos.com";
+        gord.company = "tinyHippos Inc";
+        gord.title = "Code Poet";
+        gord.address = "121 Charles Street W, Kitchener, Ontario, Canada";
+
+        dan = new AddressBookItem();
+        dan.addressBookItemId = "1";
+        dan.fullName = "Dan Silivestru";
+        dan.eMail = "dan@tinyHippos.com";
+        dan.company = "tinyHippos Inc";
+        dan.title = "Co-Founder And Chief Technology Officer";
+        dan.address = "121 Charles Street W, Kitchener, Ontario, Canada";
+
+        pj = new AddressBookItem();
+        pj.addressBookItemId = "2";
+        pj.fullName = "PJ Lowe";
+        pj.eMail = "pj@tinyHippos.com";
+        pj.company = "tinyHippos Inc";
+        pj.title = "Co-Founder And Chief Operations Officer";
+        pj.address = "121 Charles Street W, Kitchener, Ontario, Canada";
+
+        brent = new AddressBookItem();
+        brent.addressBookItemId = "2";
+        brent.fullName = "Brent Lintner";
+        brent.eMail = "brent@tinyHippos.com";
+        brent.company = "tinyHippos Inc";
+        brent.title = "Co-Founder And Chief Operations Officer";
+        brent.address = "121 Charles Street W, Kitchener, Ontario, Canada";
+
+        mark = new AddressBookItem();
+        mark.addressBookItemId = "3";
+        mark.fullName = "Mark McArdle";
+        mark.eMail = "mark@tinyHippos.com";
+        mark.company = "tinyHippos Inc";
+        mark.title = "Chief Executive Officer";
+        mark.address = "121 Charles Street W, Kitchener, Ontario, Canada";
+
+        contacts.push(gord);
+        contacts.push(dan);
+        contacts.push(pj);
+        contacts.push(brent);
+        contacts.push(mark);
+
+        _saveData(constants.PIM.ADDRESS_LIST_KEY, contacts);
+    }
+    return contacts.map(_toAddressBookItem);
+}
+
+function _getEvents() {
+    var events = _getData(constants.PIM.CALENDAR_LIST_KEY);
+    return events.map(_toCalendarItem);
+}
+
+function _get(type, id, fetchIDFunc) {
+    var items = _getData(type);
+    return items.reduceRight(function (match, item) {
+        return fetchIDFunc(item) === id ? item : match;
+    }, null);
+}
+
+function _getAddressBookID(item) {
+    return item.addressBookItemId;
+}
+
+function _getCalendarID(item) {
+    return item.calendarItemId;
+}
+
+function _getContact(id) {
+    return _toAddressBookItem(_get(constants.PIM.ADDRESS_LIST_KEY, id, _getAddressBookID));
+}
+
+function _getEvent(id) {
+    return _toCalendarItem(_get(constants.PIM.CALENDAR_LIST_KEY, id, _getCalendarID));
+}
+
+function _add(type, item, idProp) {
+    var items = _getData(type);
+
+    if (!item[idProp]) {
+        item[idProp] = Math.uuid(undefined, 16);
+    }
+
+    items.push(item);
+    _saveData(type, items);
+}
+
+function _delete(type, id, fetchIDFunc) {
+    var items = _getData(type);
+
+    _saveData(type, items.filter(function (item) {
+        return fetchIDFunc(item) !== id;
+    }));
+}
+
+function _validateArgs(min, max, len) {
+    utils.validateNumberOfArguments(min, max, len,
+        ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception());
+}
+
+function _validateType(arg, argType) {
+    utils.validateArgumentType(arg, argType,
+        ExceptionTypes.INVALID_PARAMETER,  "argument of wrong type provided",
+        new Exception());
+}
+
+function _validateAddressBookItem(item) {
+    if ((item instanceof AddressBookItem) === false) {
+        exception.raise(ExceptionTypes.INVALID_PARAMETER, "invalid contact, not instance of AddressBookItem.", new Exception());
+    }
+}
+
+_self = {
+    addAddressBookItem: function (contact) {
+        _validateArgs(1, 1, arguments.length);
+        _validateAddressBookItem(contact);
+
+        _add(constants.PIM.ADDRESS_LIST_KEY, contact, "addressBookItemId");
+    },
+    createAddressBookGroup: function (groupName) {
+        _throwUnsupportedException("Widget.PIM.createAddressBookGroup");
+    },
+    createAddressBookItem: function () {
+        return new AddressBookItem();
+    },
+    deleteAddressBookItem: function (contactid) {
+        _validateArgs(1, 1, arguments.length);
+        _validateType(contactid, "string");
+        _delete(constants.PIM.ADDRESS_LIST_KEY, contactid, _getAddressBookID);
+    },
+    deleteAddressBookGroup: function (groupName) {
+        _throwUnsupportedException("Widget.PIM.deleteAddressBookGroup");
+    },
+    getAddressBookItem: function (contactid) {
+        _validateArgs(1, 1, arguments.length);
+        _validateType(contactid, "string");
+        return _getContact(contactid);
+    },
+    getAddressBookItemsCount: function () {
+        _validateArgs(0, 0, arguments.length);
+        var items = _getContacts();
+        return items.length;
+    },
+    getAvailableAddressGroupNames: function () {
+        _throwUnsupportedException("Widget.PIM.getAvailableAddressGroupNames");
+    },
+    getAddressBookGroupMembers: function (groupName) {
+        _throwUnsupportedException("Widget.PIM.getAddressBookGroupMembers");
+    },
+    findAddressBookItems: function (comparisonContact, startInx, endInx) {
+        _validateArgs(3, 3, arguments.length);
+        utils.validateMultipleArgumentTypes([comparisonContact, startInx, endInx], ["object", "number", "number"], ExceptionTypes.INVALID_PARAMETER,  "argument of wrong type provided",
+            new Exception());
+
+        if (endInx < 0) {
+            exception.raise(ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception());
+        }
+
+        startInx = startInx < 0 ? 0 : startInx;
+
+        var contacts = _getContacts();
+        utils.find(comparisonContact, contacts, startInx, endInx, _self.onAddressBookItemsFound);
+    },
+
+    addCalendarItem: function (calendarItem) {
+        _validateArgs(1, 1, arguments.length);
+        _add(constants.PIM.CALENDAR_LIST_KEY, calendarItem, "calendarItemId");
+    },
+    deleteCalendarItem: function (calendarId) {
+        _validateArgs(1, 1, arguments.length);
+        _delete(constants.PIM.CALENDAR_LIST_KEY, calendarId, _getCalendarID);
+    },
+    getCalendarItem: function (calendarId) {
+        _validateArgs(1, 1, arguments.length);
+        return _getEvent(calendarId);
+    },
+    findCalendarItems: function (itemToMatch, startInx, endInx) {
+        _validateArgs(1, 3, arguments.length);
+        var events = _getEvents();
+        utils.find(itemToMatch, events, startInx, endInx, _self.onCalendarItemsFound);
+    },
+    getCalendarItems: function (startTime, endTime) {
+        var events = _getEvents();
+
+        return events.reduce(function (matches, event) {
+            if (event.eventStartTime >= startTime && event.eventStartTime <= endTime) {
+                matches.push(event);
+            }
+            return matches;
+        }, []);
+    },
+    exportAsVCard: function (addressBookItems) {
+        _throwUnsupportedException("Widget.PIM.exportAsVCard");
+    },
+
+    onAddressBookItemsFound: undefined, // function (addressBookItemsFound) { }
+    onCalendarItemsFound: undefined, // function (calendarItemsFound) { }
+    onCalendarItemAlert: undefined, // function (calendarItem) { }
+    onVCardExportingFinish: undefined // function (vCardFilePath) { }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/WidgetManager', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var exception = require('ripple/exception'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+    Exception = require('ripple/platform/wac/1.0/Exception');
+
+module.exports = {
+    // This method is used to check the installation status of a specific widget.
+    checkWidgetInstallationStatus: function () {
+
+        exception.raise(ExceptionTypes.UNSUPPORTED, "WidgetManager.checkWidgetInstallationStatus not supported", new Exception());
+    }
+};
+
+});
+require.define('ripple/platform/wac/1.0/ApplicationTypes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    constants = require('ripple/constants'),
+    _self = {};
+
+utils.forEach(constants.PLATFORMS.WAC.APPLICATIONS, function (application) {
+    _self.__defineGetter__(application, function () {
+        return application;
+    });
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/EventRecurrenceTypes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    NOT_REPEAT: "NOT_REPEAT",
+    DAILY: "DAILY",
+    EVERY_WEEKDAY: "EVERY_WEEKDAY",
+    WEEKLY_ON_DAY: "WEEKLY_ON_DAY",
+    MONTHLY_ON_DAY: "MONTHLY_ON_DAY",
+    MONTHLY_ON_DAY_COUNT: "MONTHLY_ON_DAY_COUNT",
+    YEARLY: "YEARLY"
+};
+
+});
+require.define('ripple/platform/wac/1.0/PowerInfo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    event = require('ripple/event'),
+    _console = require('ripple/console'),
+    deviceSettings = require('ripple/deviceSettings'),
+    _lastPercentRemaining;
+
+_self = {
+    isCharging: undefined,
+    percentRemaining: undefined,
+
+    onChargeStateChange: undefined,
+    onLowBattery: undefined,
+    onChargeLevelChange: undefined
+};
+
+function _getCurrentChargeState(percentRemaining, isCharging) {
+    var batteryState;
+    if (percentRemaining === 100 && isCharging) {
+        batteryState = "full";
+    }
+    else if (!isCharging) {
+        batteryState = "discharging";
+    }
+    else {
+        batteryState = "charging";
+    }
+    return batteryState;
+}
+
+event.on("DeviceBatteryStateChanged", function (isCharging) {
+    var callback = _self.onChargeStateChange,
+        msg = "",
+        batteryLevel = _self.percentRemaining,
+        batteryState;
+
+    batteryState = _getCurrentChargeState(batteryLevel, isCharging);
+
+    msg += "Fired onChargeStateChange with batteryState: " + batteryState;
+
+    if (callback && typeof callback === "function") {
+        callback.apply(null, [batteryState]);
+    }
+    else {
+        msg += " --> BUT there was no registered callback found.";
+    }
+
+    _console.log(msg);
+});
+
+event.on("DeviceBatteryLevelChanged", function (percentRemaining) {
+
+    var callback = _self.onChargeLevelChange,
+        lowBatteryCallback = _self.onLowBattery,
+        msg = "Fired onChargeLevelChange with percentRemaining: " + percentRemaining;
+
+    // blah, stupid Options returning strings
+    percentRemaining = parseInt(percentRemaining, 10);
+
+    if (callback && typeof callback === "function") {
+        callback.apply(null, [percentRemaining]);
+    }
+    else {
+        msg += " --> BUT there was no registered callback found.";
+    }
+
+    _console.log(msg);
+
+    if (percentRemaining <= 10) {
+
+        msg = "Fired onLowBattery with percentRemaining: " + percentRemaining;
+
+        if (lowBatteryCallback && typeof lowBatteryCallback === "function") {
+            lowBatteryCallback.apply(null, [percentRemaining]);
+        }
+        else {
+            msg += " --> BUT there was no registered callback found.";
+        }
+
+        _console.log(msg);
+    }
+
+    if (percentRemaining === 100 || (percentRemaining < 100 && _lastPercentRemaining === 100)) {
+        event.trigger("DeviceBatteryStateChanged", [_self.isCharging]);
+    }
+
+    _lastPercentRemaining = percentRemaining;
+
+});
+
+_self.__defineGetter__("isCharging", function () {
+    return deviceSettings.retrieveAsBoolean("PowerInfo.isCharging");
+});
+
+_self.__defineGetter__("percentRemaining", function () {
+    return deviceSettings.retrieveAsInt("PowerInfo.percentRemaining");
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/DeviceInfo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    deviceSettings = require('ripple/deviceSettings'),
+    platform = require('ripple/platform'),
+    devices = require('ripple/devices'),
+    _self;
+
+_self = {
+    ownerInfo: undefined, // return AddressBookItem
+    phoneColorDepthDefault: undefined,
+    phoneFirmware: undefined,
+    phoneManufacturer: undefined,
+    phoneModel: undefined,
+    phoneOS: undefined,
+    phoneSoftware: undefined,
+    phoneScreenHeightDefault: undefined,
+    phoneScreenWidthDefault: undefined,
+    totalMemory: undefined
+};
+
+function _getDeviceAttribute(attr) {
+    var devicePointer = devices.getCurrentDevice();
+    utils.forEach(attr.split("."), function (dot) {
+        devicePointer = devicePointer[dot];
+    });
+    return devicePointer;
+}
+
+_self.__defineGetter__("phoneColorDepthDefault", function () {
+    return deviceSettings.retrieveAsInt("DeviceInfo.phoneColorDepthDefault");
+});
+
+_self.__defineGetter__("phoneFirmware", function () {
+    return _getDeviceAttribute("firmware");
+});
+
+_self.__defineGetter__("phoneManufacturer", function () {
+    return _getDeviceAttribute("manufacturer");
+});
+
+_self.__defineGetter__("phoneOS", function () {
+    return _getDeviceAttribute("osName") + " " + _getDeviceAttribute("osVersion");
+});
+
+_self.__defineGetter__("phoneModel", function () {
+    return _getDeviceAttribute("model");
+});
+
+_self.__defineGetter__("phoneSoftware", function () {
+    return _getDeviceAttribute("osVersion");
+});
+
+_self.__defineGetter__("phoneScreenHeightDefault", function () {
+    return _getDeviceAttribute("screen.height");
+});
+
+_self.__defineGetter__("phoneScreenWidthDefault", function () {
+    return _getDeviceAttribute("screen.width");
+});
+
+_self.__defineGetter__("totalMemory", function () {
+    return deviceSettings.retrieveAsInt("DeviceInfo.totalMemory");
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/CallRecordTypes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    RECEIVED: "received",
+    OUTGOING: "outgoing",
+    MISSED: "missed"
+};
+
+});
+require.define('ripple/platform/wac/1.0/Device', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    exception = require('ripple/exception'),
+    _console = require('ripple/console'),
+    utils = require('ripple/utils'),
+    notifications = require('ripple/notifications'),
+    ApplicationTypes = require('ripple/platform/wac/1.0/ApplicationTypes'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+    _applicationTypes = {
+        FILES: "FILES",
+        MEDIAPLAYER: "MEDIAPLAYER",
+        PHONECALL: "PHONECALL",
+        PICTURES: "PICTURES"
+    },
+    _self;
+
+function _throwUnsupportedException(method) {
+    exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
+}
+
+_self = {
+    // Properties
+    clipboardString: undefined,
+    widgetEngineName: undefined,
+    widgetEngineProvider: undefined,
+    widgetEngineVersion: undefined,
+
+    // Methods
+    getAvailableApplications: function () {
+        return constants.PLATFORMS.WAC.APPLICATIONS || [];
+    },
+
+    getDirectoryFileNames: function () {
+        _throwUnsupportedException("Device.getDirectoryFileNames");
+    },
+    getFile: function () {
+        _throwUnsupportedException("Device.getFile");
+    },
+
+    launchApplication: function launchApplication(application, startParameter) {
+        if (!application || typeof(application) !== "string") {
+            exception.raise(ExceptionTypes.INVALID_PARAMETER,
+                    "Invalid argument 'application' at Device.launchApplication(): expected to be of type 'string' but was of type: " + (application ? typeof(application) : "null"),
+                    Exception);
+        }
+
+        if (startParameter && typeof(startParameter) !== "string") {
+            exception.raise(ExceptionTypes.INVALID_PARAMETER,
+                    "Invalid argument 'startParameter' at Device.launchApplication(): expected to be 'string' but was : " + typeof(startParameter),
+                    Exception);
+        }
+
+        // rudimentary implementation for now
+        var message = "The widget has requested application: '" + application + "' to be launched. \n\n";
+
+        if (startParameter) {
+            message += "The following start parameter was sent in: " + startParameter + "\n\n";
+        }
+
+        if (_applicationTypes[application] && !startParameter) {
+            message += "Launching this application can also be done with an optional startParameter which was not provided" + "\n\n";
+        }
+
+        if (!ApplicationTypes[application]) {
+            message += "Note: the application requested is not part of the common values specified by the WAC API.";
+        }
+
+        notifications.openNotification("normal", message);
+        _console.log(message);
+    },
+
+    copyFile: function () {
+        _throwUnsupportedException("Device.copyFile");
+    },
+    deleteFile: function () {
+        _throwUnsupportedException("Device.deleteFile");
+    },
+    findFiles: function () {
+        _throwUnsupportedException("Device.findFiles");
+    },
+    getFileSystemRoots: function () {
+        _throwUnsupportedException("Device.getFileSystemRoots");
+    },
+    getFileSystemSize: function () {
+        _throwUnsupportedException("Device.getFileSystemSize");
+    },
+    moveFile: function () {
+        _throwUnsupportedException("Device.moveFile");
+    },
+    onFilesFound: function () {
+        _throwUnsupportedException("Device.onFilesFound");
+    },
+    setRingtone: function () {
+        _throwUnsupportedException("Device.setRingtone");
+    },
+
+    vibrate: function (duration) {
+        utils.validateArgumentType(duration, "number", ExceptionTypes.INVALID_PARAMETER, "duration paramter is not a number", new Exception());
+        notifications.openNotification("normal", "Vibrating for " + duration + " second(s).");
+    }
+
+};
+
+_self.__defineGetter__("widgetEngineName", function () {
+    return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_NAME;
+});
+
+_self.__defineGetter__("widgetEngineProvider", function () {
+    return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_PROVIDER;
+});
+
+_self.__defineGetter__("widgetEngineVersion", function () {
+    return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_VERSION;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/DataNetworkInfo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    _console = require('ripple/console'),
+    deviceSettings = require('ripple/deviceSettings'),
+    DataNetworkConnectionTypes = require('ripple/platform/wac/1.0/DataNetworkConnectionTypes'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+
+_self = {
+    isDataNetworkConnected: undefined,
+    networkConnectionType: undefined,
+    onNetworkConnectionChanged: undefined,
+
+    getNetworkConnectionName: function (networkConnectionType) {
+        var foundConnectionType;
+        utils.validateArgumentType(networkConnectionType, "string", ExceptionTypes.INVALID_PARAMETER, "networkConnectionType is invalid, expected a string", new Exception());
+        foundConnectionType = DataNetworkConnectionTypes[networkConnectionType.toUpperCase()];
+        return foundConnectionType || null;
+    }
+};
+
+event.on("DataNetworkConnectionChanged", function (newConnectionName) {
+    var callback = _self.onNetworkConnectionChanged,
+        msg = "Fired onNetworkConnectionChanged with newConnectionName: " + newConnectionName;
+
+    if (callback && typeof callback === "function") {
+        callback.apply(null, [newConnectionName]);
+    }
+    else {
+        msg += " --> BUT there was no registered callback found.";
+    }
+
+    _console.log(msg);
+});
+
+_self.__defineGetter__("isDataNetworkConnected", function () {
+    return deviceSettings.retrieveAsBoolean("DataNetworkInfo.isDataNetworkConnected");
+});
+
+_self.__defineGetter__("networkConnectionType", function () {
+    var value = deviceSettings.retrieve("DataNetworkInfo.networkConnectionType");
+    return value instanceof Array ? value : [value];
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/AudioPlayer', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    exception = require('ripple/exception'),
+    utils = require('ripple/utils'),
+    fileSystem = require('ripple/fileSystem'),
+    _console = require('ripple/console'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+    _self,
+    _state = null,
+    _STATES = constants.MULTIMEDIA.AUDIO_STATES,
+    _currentAudioFile,
+    _audio, _loopCount;
+
+event.on("MultimediaAudioStateChanged", function updateAudioState(state) {
+    _state = state;
+    if (typeof _self.onStateChange === 'function') {
+        _self.onStateChange.apply(_self, arguments);
+    }
+});
+
+_audio = utils.createElement("audio", {
+    "id": "multimedia-audio"
+});
+
+_audio.addEventListener('error', function () {
+    _console.warn("AudioPlayer encountered an error: " + _audio.error.code);
+    if (_audio.error.code === 4) {
+        _console.warn("AudioPlayer error 4 could be caused by missing codecs");
+    }
+    _state = null;
+    event.trigger("MultimediaAudioStateChanged", [null], true);
+});
+
+_audio.addEventListener('ended', function handleAudioEnded() {
+    event.trigger("MultimediaAudioStateChanged", [_STATES.COMPLETED], true);
+    if (_loopCount > 1) {
+        _self.open(_currentAudioFile);
+        _self.play(_loopCount--);
+    }
+});
+
+document.getElementById("ui").appendChild(_audio);
+
+function _validateAndSet(state, validStates, callbackBeforeSuccess) {
+    var i, valid = false;
+
+    for (i = 0; i < validStates.length; i++) {
+        if (validStates[i] === _state) {
+            valid = true;
+        }
+    }
+
+    if (!valid) {
+        _console.warn("Attempted to initiate AudioPlayer." + state +
+            " in invalid state. current state: " + _state);
+    } else {
+        if (typeof(callbackBeforeSuccess) === "function") {
+            callbackBeforeSuccess.apply();
+        }
+        event.trigger("MultimediaAudioStateChanged", [state], true);
+    }
+
+    return valid;
+}
+
+function _validateAudioType(fileUrl) {
+    var matched = fileUrl.match(/\.(\w*)$/),
+        type = matched ? matched[1] : "";
+
+    if (_audio && _audio.canPlayType("audio/" + type) === "") {
+        _console.warn("Attempting to load an audio that might not work in the current browser [" + fileUrl + "]");
+    }
+}
+
+_self = {
+    onStateChange: undefined,
+
+    open: function (fileUrl) {
+        utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.open wrong number of arguments", new Exception());
+        utils.validateArgumentType(fileUrl, "string", ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.open invalid parameter! expected string, fileUrl: " +
+            fileUrl, new Exception());
+
+        if (fileUrl.match(/^rtsp:\/\//)) {
+            exception.raise(exception.types.MethodNotImplemented, "rtsp:// scheme not yet supported. sorry :(");
+        }
+
+        _validateAndSet(_STATES.OPENED, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED, null], function () {
+            _validateAudioType(fileUrl);
+            _currentAudioFile = fileSystem.getURI(fileUrl);
+            _audio.setAttribute("src", _currentAudioFile);
+            _audio.load();
+        });
+    },
+
+    play: function (repeatTimes) {
+        utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.play wrong number of arguments", new Exception());
+        utils.validateArgumentType(repeatTimes, "integer", ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.play invalid parameter! expected integer, repeatTimes: " + repeatTimes, new Exception());
+
+        if (repeatTimes < 0) {
+            exception.raise(ExceptionTypes.INVALID_PARAMETER, "value of repeatTimes must be greater than 0", new Exception());
+        }
+
+        if (repeatTimes !== 0) {
+            _validateAndSet(_STATES.PLAYING, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED], function () {
+                _loopCount = repeatTimes;
+                _audio.play();
+            });
+        }
+    },
+
+    pause: function () {
+        _validateAndSet(_STATES.PAUSED, [_STATES.PLAYING], function () {
+            _audio.pause();
+        });
+    },
+
+    resume: function () {
+        _validateAndSet(_STATES.PLAYING, [_STATES.PAUSED], function () {
+            _audio.play();
+        });
+    },
+
+    stop: function () {
+        _validateAndSet(_STATES.STOPPED, [_STATES.PAUSED, _STATES.PLAYING], function () {
+            try {
+                _audio.pause();
+                _audio.currentTime = 0;
+            } catch (e) {
+                //HACK: do nothing, this could throw a dom exception 11 sometimes when playing an mp3 or before the file has loaded.
+                //see http://developer.palm.com/distribution/viewtopic.php?f=11&t=7568
+            }
+        });
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/Account', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var deviceSettings = require('ripple/deviceSettings'),
+    _self;
+
+_self = {
+    accountName: undefined,
+    accountId: undefined
+};
+
+_self.__defineGetter__("accountName", function () {
+    return deviceSettings.retrieve("Account.accountName");
+});
+
+_self.__defineGetter__("accountId", function () {
+    return deviceSettings.retrieve("Account.accountId");
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/Multimedia', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    VideoPlayer = require('ripple/platform/wac/1.0/VideoPlayer'),
+    AudioPlayer = require('ripple/platform/wac/1.0/AudioPlayer'),
+    constants = require('ripple/constants'),
+    _volume = 5,
+    _audioState,
+    _videoState,
+    _self;
+
+event.on("MultimediaVolumeChanged", function updateVolume(volume) {
+    _volume = volume;
+});
+
+event.on("MultimediaAudioStateChanged", function updateAudioState(state) {
+    _audioState = state;
+});
+
+event.on("MultimediaVideoStateChanged", function updateVideoState(state) {
+    _videoState = state;
+});
+
+_self = {
+
+    isAudioPlaying: undefined,
+    isVideoPlaying: undefined,
+
+    getVolume: function () {
+        return _volume;
+    },
+
+    stopAll: function () {
+        VideoPlayer.stop();
+        AudioPlayer.stop();
+    }
+};
+
+_self.__defineGetter__("isAudioPlaying", function () {
+    return _audioState === constants.MULTIMEDIA.AUDIO_STATES.PLAYING;
+});
+
+_self.__defineGetter__("isVideoPlaying", function () {
+    return _videoState === "playing";
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/MessageQuantities', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    totalMessageCnt: undefined,
+    totalMessageReadCnt: undefined,
+    totalMessageUnreadCnt: undefined
+};
+
+});
+require.define('ripple/platform/wac/1.0/Attachment', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function () {
+    this.fileName = "";
+    this.MIMEType = "";
+    this.size = 0;
+};
+
+});
+require.define('ripple/platform/wac/1.0/Camera', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var exception = require('ripple/exception'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+    constants = require('ripple/constants'),
+    _console = require('ripple/console'),
+    utils = require('ripple/utils'),
+    notifications = require('ripple/notifications'),
+    _currentlySet,
+    _img,
+    _buttons,
+    _self,
+    _videoCapture;
+
+
+function _populateWindow(domObject) {
+    var record = document.createElement("button"),
+        pause = document.createElement("button"),
+        stop = document.createElement("button");
+
+    _img = document.createElement("img");
+    _img.setAttribute("id", "jil-camera-window");
+    //_img.setAttribute("src", document.querySelector("#extension-url").innerHTML + constants.CAMERA.WINDOW_ANIMATION);
+    _img.setAttribute("src", document.documentURI.replace(/index\.html$/, "") + constants.CAMERA.WINDOW_ANIMATION);
+    _img.setAttribute("width", "100%");
+    _currentlySet = domObject;
+    domObject.appendChild(_img);
+
+    _buttons = document.createElement("div");
+    _buttons.setAttribute("id", "jil-camera-window-buttons");
+    _buttons.setAttribute("style", "display: none");
+
+    record.setAttribute("id", "jil-camera-window-buttons-record");
+    record.innerHTML = "Record";
+    pause.setAttribute("id", "jil-camera-window-buttons-pause");
+    pause.innerHTML = "Pause";
+    stop.setAttribute("id", "jil-camera-window-buttons-stop");
+    stop.innerHTML = "Stop";
+    stop.addEventListener("click", _self.stopVideoCapture);
+
+    _buttons.appendChild(record);
+    _buttons.appendChild(pause);
+    _buttons.appendChild(stop);
+
+    domObject.appendChild(_buttons);
+
+}
+
+function _verifySetWindow(method) {
+    if (!_img) {
+        exception.raise(ExceptionTypes.UNKNOWN, "Camera." +
+          method + " was (most likely) called before using the setWindow method.", new Exception());
+    }
+}
+
+_self = {
+    onCameraCaptured: undefined, //function (fileName) { }
+
+    captureImage: function (fileName, lowRes) {
+        utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "captureImage invalid number of parameters", new Exception());
+        utils.validateMultipleArgumentTypes([fileName, lowRes], ['string', 'boolean'], ExceptionTypes.INVALID_PARAMETER, "invalid parameter type", new Exception());
+
+        _verifySetWindow("captureImage");
+        var msg = constants.CAMERA.WARNING_TEXT;
+        msg = msg.replace("{file}", fileName);
+        notifications.openNotification("normal", msg);
+        _console.log("simulated saved image as: " + fileName);
+        if (_self.onCameraCaptured) {
+            _self.onCameraCaptured.apply(_self, [fileName]);
+        }
+
+        return fileName;
+    },
+    setWindow: function (domObject) {
+
+        if (_currentlySet) {
+            _currentlySet.removeChild(_img);
+            _currentlySet.removeChild(_buttons);
+            _currentlySet = null;
+            _img = null;
+            _buttons = null;
+        }
+        if (domObject !== null) {
+            _populateWindow(domObject);
+        }
+    },
+    startVideoCapture: function (fileName, lowRes, maxDurationSeconds, showDefaultControls) {
+        _verifySetWindow("startVideoCapture");
+        utils.validateNumberOfArguments(1, 4, arguments.length, ExceptionTypes.INVALID_PARAMETER, "startVideoCapture invalid number of parameters", new Exception());
+        utils.validateMultipleArgumentTypes(
+            [fileName, lowRes, maxDurationSeconds, showDefaultControls],
+            ['string', 'boolean', 'integer', 'boolean'],
+            ExceptionTypes.INVALID_PARAMETER,
+            "invalid parameter type", new Exception());
+        _console.log("started recording video");
+        var interval = window.setTimeout(function () {
+            _self.stopVideoCapture();
+        }, maxDurationSeconds * 1000);
+
+        if (showDefaultControls) {
+            _buttons.removeAttribute("style");
+        }
+
+        _videoCapture = {
+            fileName: fileName,
+            stop: function () {
+                window.clearInterval(interval);
+                var msg = constants.CAMERA.WARNING_TEXT;
+                msg = msg.replace("{file}", fileName);
+                notifications.openNotification("normal", msg);
+                if (_self.onCameraCaptured) {
+                    _self.onCameraCaptured.apply(_self, [fileName]);
+                }
+            }
+        };
+
+        return fileName;
+    },
+    stopVideoCapture: function () {
+        utils.validateNumberOfArguments(0, 0, arguments.length, ExceptionTypes.INVALID_PARAMETER, "stopVideoCapture invalid number of parameters", new Exception());
+        if (_videoCapture) {
+            _console.log("simulated saving a video as: " + _videoCapture.fileName);
+            if (_buttons) {
+                _buttons.setAttribute("style", "display: none");
+            }
+            _videoCapture.stop();
+            _videoCapture = null;
+        }
+    }
+
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/wac/1.0/Exception', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = function () {
+    this.message = "";
+    this.type =  "";
+
+    this.toString = function () {
+        var result = this.type + ': "' + this.message + '"';
+
+        if (this.stack) {
+            result += "\n" + this.stack;
+        }
+        return result;
+    };
+};
+
+});
+require.define('ripple/platform/wac/1.0/Messaging', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var exception = require('ripple/exception'),
+    utils = require('ripple/utils'),
+    constants = require('ripple/constants'),
+    notifications = require('ripple/notifications'),
+    _console = require('ripple/console'),
+    Message = require('ripple/platform/wac/1.0/Message'),
+    MessageTypes = require('ripple/platform/wac/1.0/MessageTypes'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes');
+
+function _throwUnsupportedException(method) {
+    exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
+}
+
+module.exports = {
+    onMessageArrived: undefined,
+    onMessageSendingFailure: undefined,
+    onMessagesFound: undefined,
+
+    createMessage: function (messageType) {
+        utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "createMessage invalid number of arguments", new Exception());
+        utils.validateArgumentType(messageType, "string", ExceptionTypes.INVALID_PARAMETER, "createMessage invalid arguments", new Exception());
+
+        if (!utils.some(MessageTypes, function (value) {
+                return value === messageType;
+            })) {
+            exception.raise(ExceptionTypes.INVALID_PARAMETER, "createMessage invalid arguments", new Exception());
+        }
+
+        var message = new Message();
+        message.messageType = messageType;
+
+        return message;
+    },
+    deleteMessage: function () {
+        _throwUnsupportedException("Messaging.deleteMessage");
+    },
+    getMessage: function () {
+        _throwUnsupportedException("Messaging.getMessage");
+    },
+    getMessageQuantities: function () {
+        _throwUnsupportedException("Messaging.getMessageQuantities");
+    },
+    sendMessage: function (msg) {
+        utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.UNSUPPORTED, "sendMessage invalid number of arguments", new Exception());
+        if (msg instanceof Message === false) {
+            exception.raise(ExceptionTypes.INVALID_PARAMETER, "expected a valid Message object", new Exception());
+        }
+
+        //TODO: Must be modded to fail and to then call the onMessageSendingFailure callback
+        var message = "Sent " + msg.messageType + " " + msg.messageId + " to " + msg.destinationAddress;
+
+        // insert fail check here
+        notifications.openNotification("normal", message);
+        _console.log(message);
+    },
+    moveMessageToFolder: function () {
+        _throwUnsupportedException("Messaging.moveMessageToFolder");
+    },
+    copyMessageToFolder: function () {
+        _throwUnsupportedException("Messaging.copyMessageToFolder");
+    },
+    createFolder: function () {
+        _throwUnsupportedException("Messaging.createFolder");
+    },
+    deleteFolder: function () {
+        _throwUnsupportedException("Messaging.deleteFolder");
+    },
+    getFolderNames: function () {
+        _throwUnsupportedException("Messaging.getFolderNames");
+    },
+    findMessages: function () {
+        _throwUnsupportedException("Messaging.findMessages");
+    },
+    getCurrentEmailAccount: function () {
+        _throwUnsupportedException("Messaging.getCurrentEmailAccount");
+    },
+    getEmailAccounts: function () {
+        _throwUnsupportedException("Messaging.getEmailAccounts");
+    },
+    setCurrentEmailAccount: function () {
+        _throwUnsupportedException("Messaging.setCurrentEmailAccount");
+    },
+    deleteEmailAccount: function () {
+        _throwUnsupportedException("Messaging.deleteEmailAccount");
+    }
+
+};
+
+});
+require.define('ripple/platform/wac/1.0/spec/events', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var event = require('ripple/event');
+
+module.exports = {
+    "WidgetWakeup": {
+        callback: function () {
+            event.trigger("WidgetWakeup");
+        }
+    },
+    "WidgetMaximize": {
+        callback: function () {
+            event.trigger("WidgetMaximize");
+        }
+    },
+    "WidgetFocus": {
+        callback: function () {
+            event.trigger("WidgetFocus");
+        }
+    },
+    "WidgetRestore": {
+        callback: function () {
+            event.trigger("WidgetRestore");
+        }
+    }
+};
+
+});
+require.define('ripple/platform/wac/1.0/spec/device', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    event = require('ripple/event');
+
+module.exports = {
+    "AccountInfo": {
+        "phoneUserUniqueId": {
+            "name": "User Unique Id",
+            "control": {
+                "type": "text",
+                "value": new Date().getTime().toString()
+            }
+        },
+        "phoneMSISDN":  {
+            "name": "MSISDN",
+            "control": {
+                "type": "text",
+                "value": "15199999999"
+            }
+        },
+        "phoneOperatorName":  {
+            "name": "Operator Name",
+            "control": {
+                "type": "text",
+                "value": ""
+            }
+        },
+        "userAccountBalance":  {
+            "name": "Account Balance",
+            "control": {
+                "type": "number",
+                "value": 0
+            }
+        },
+        "userSubscriptionType":  {
+            "name": "Subscription Type",
+            "control": {
+                "type": "select",
+                "value": "other"
+            },
+            "options": {
+                "other": "other",
+                "prepaid": "prepaid",
+                "postpaid": "postpaid"
+            }
+        }
+    },
+    "RadioInfo": {
+        "isRoaming": {
+            "name": "Is Roaming",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            },
+            "callback": function () {
+                event.trigger("RadioSignalSourceChanged");
+            }
+        },
+        "isRadioEnabled":  {
+            "name": "Is Radio Enabled",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        },
+        "radioSignalSource": {
+            "name": "Radio Signal Source",
+            "control": {
+                "type": "select",
+                "value": "GSM"
+            },
+            // TODO: try not to duplicate from RadioSignalSourceTypes
+            "options": {
+                "CDMA": "cdma",
+                "GSM": "gsm",
+                "LTE": "lte",
+                "TDSCDMA": "tdscdma",
+                "WCDMA": "wcdma"
+            },
+            "callback": function () {
+                event.trigger("RadioSignalSourceChanged");
+            }
+        },
+        "radioSignalStrengthPercent": {
+            "name": "Signal Strength %",
+            "control": {
+                "type": "select",
+                "value": 80
+            },
+            "options": (function () {
+                var i,
+                    optionList = {};
+
+                for (i = 0; i <= 100; i++) {
+                    optionList[i] = i;
+                }
+
+                return optionList;
+            }())
+        }
+    },
+    "Config": {
+        "ringtoneVolume": {
+            "name": "Ringtone Volume",
+            "control": {
+                "type": "select",
+                "value": 10
+            },
+            "options": (function () {
+                var i,
+                    optionList = {};
+
+                for (i = 0; i <= 10; i++) {
+                    optionList[i] = i;
+                }
+
+                return optionList;
+            }())
+        },
+        "msgRingtoneVolume":  {
+            "name": "Msg Ringtone Volume",
+            "control": {
+                "type": "select",
+                "value": 10
+            },
+            "options": (function () {
+                var i,
+                    optionList = {};
+
+                for (i = 0; i <= 10; i++) {
+                    optionList[i] = i;
+                }
+
+                return optionList;
+            }())
+        },
+        "vibrationSetting":  {
+            "name": "Vibration",
+            "control": {
+                "type": "select",
+                "value": "off"
+            },
+            "options": {
+                "on": "ON",
+                "off": "OFF"
+            }
+        }
+    },
+    "Account": {
+        "accountName":  {
+            "name": "Name",
+            "control": {
+                "type": "text",
+                "value": ""
+            }
+        },
+        "accountId":  {
+            "name": "Id",
+            "control": {
+                "type": "text",
+                "value": ""
+            }
+        }
+    },
+    "DeviceInfo": {
+        "totalMemory": {
+            "name": "Total Memory",
+            "control": {
+                "type": "range",
+                "value": 262144,
+                "min": 0,
+                "max": 4096000
+            }
+        },
+        "phoneColorDepthDefault": {
+            "name": "Color Depth",
+            "control": {
+                "type": "number",
+                "value": 24
+            }
+        }
+    },
+    "DeviceStateInfo": {
+        "availableMemory": {
+            "name": "Available Memory",
+            "control": {
+                "type": "range",
+                "value": 262144,
+                "min": 0,
+                "max": 4096000
+            }
+        },
+        "keypadLightOn":   {
+            "name": "Keypad Light On",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            }
+        },
+        "backLightOn": {
+            "name": "Back Light On",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            }
+        },
+        "audioPath":  {
+            "name": "Audio Path",
+            "control": {
+                "type": "select",
+                "value": "receiver"
+            },
+            "options": {
+                "speaker": "speaker",
+                "receiver": "receiver",
+                "earphone": "earphone"
+            }
+        },
+        "processorUtilizationPercent":  {
+            "name": "CPU Utilization %",
+            "control": {
+                "type": "select",
+                "value": "5"
+            },
+            "options": (function () {
+                var i,
+                    optionList = {};
+
+                for (i = 0; i <= 100; i++) {
+                    optionList[i] = i;
+                }
+
+                return optionList;
+            }())
+        },
+        "language":  {
+            "name": "Language",
+            "control": {
+                "type": "select",
+                "value": "eng"
+            },
+            "options": (function () {
+                var i,
+                    optionList = {},
+                    iterator = constants.LANG.ISO6392_LIST;
+
+                for (i = 0; i <= iterator.length; i++) {
+                    optionList[iterator[i]] = iterator[i];
+                }
+
+                return optionList;
+            }())
+        }
+    },
+    "DataNetworkInfo": {
+        "isDataNetworkConnected": {
+            "name": "Data Network Is Connected",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        },
+        "networkConnectionType": {
+            "name": "Network Connection Type",
+            "control": {
+                "type": "select",
+                "value": ["GPRS"]
+            },
+            // TODO: try not to duplicate from DataNetworkConnectionTypes
+            "options": {
+                "BLUETOOTH": "bluetooth",
+                "EDGE": "edge",
+                "EVDO": "evdo",
+                "GPRS": "gprs",
+                "IRDA": "irda",
+                "LTE": "lte",
+                "ONEXRTT": "1xrtt",
+                "WIFI": "wifi"
+            },
+            "callback": function (setting) {
+                event.trigger("DataNetworkConnectionChanged", [setting]);
+            }
+        }
+    },
+    "PowerInfo": {
+        "isCharging": {
+            "name": "Battery Is Charging",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "callback": function (setting) {
+                event.trigger("DeviceBatteryStateChanged", [setting]);
+            }
+        },
+        "percentRemaining":  {
+            "name": "Battery Remaining %",
+            "control": {
+                "type": "select",
+                "value": 100
+            },
+            "options": (function () {
+                var i,
+                    optionList = {};
+
+                for (i = 0; i <= 100; i++) {
+                    optionList[i] = i;
+                }
+
+                return optionList;
+            }()),
+            "callback": function (setting) {
+                event.trigger("DeviceBatteryLevelChanged", [setting]);
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/platform/wac/1.0/spec/ui', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    plugins: [
+        "accelerometer",
+        //"deviceSettings",
+        "fileSystem",
+        "geoView",
+/*
+        "multimedia",
+        "audioPlayer",
+        "telephony",
+*/
+        "platformEvents",
+        "storage",
+        "widgetConfig"
+    ]
+};
+
+});
+require.define('ripple/platform/wac/1.0/spec/config', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var platform = require('ripple/platform'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    constants = require('ripple/constants');
+
+module.exports = {
+    fileName: "config.xml",
+    validateVersion: function (configValidationObject) {
+        var valid = true;
+        valid = !((!configValidationObject.widget.validationResult[0].attributes.xmlns.valid) ||
+            (!configValidationObject.widget.validationResult[0].attributes["xmlns:JIL"].valid));
+
+        return valid;
+    },
+    extractInfo: function (configValidationObject) {
+        if (!configValidationObject) {
+            return null;
+        }
+
+        var widgetInfo = {},
+            configFeatures,
+            configPreferences,
+            preferenceName,
+            platform;
+
+        widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
+        widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
+        widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
+        widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
+
+        widgetInfo.features = {};
+
+        configFeatures = configValidationObject.widget.children.feature.validationResult;
+        utils.forEach(configFeatures, function (f) {
+            if (f.valid === true) {
+                var feature = {id: f.attributes.name.value,
+                         required: f.attributes.required.valid};
+                widgetInfo.features[feature.id] = feature;
+            }
+        });
+
+        widgetInfo.preferences = {};
+
+        configPreferences = configValidationObject.widget.children.preference.validationResult;
+
+        platform = require('ripple/platform');
+        utils.forEach(configPreferences, function (preference) {
+            preferenceName = preference.attributes.name.value;
+            if (preferenceName) {
+                widgetInfo.preferences[preferenceName] = {
+                    "key": preferenceName,
+                    "value": preference.attributes.value.value || "",
+                    "readonly": preference.attributes.readonly.value === "true"
+                };
+
+                db.save(preferenceName,
+                        widgetInfo.preferences[preferenceName].value,
+                        platform.getPersistencePrefix(widgetInfo.id));
+            }
+        });
+
+        return widgetInfo;
+    },
+    schema: {
+        rootElement: "widget",
+        widget: {
+            nodeName: "widget",
+            required: true,
+            occurrence: 1,
+            helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in configuration document and may have following child elments: name,description,icon,author,license,content,maximum_display_mode,update,feature,access,billing. \"widget\" element MAY have following attributes: id,version,height,width,xml:lang",
+            attributes: {
+                xmlns: {
+                    attributeName: "xmlns",
+                    required: true,
+                    type: "list",
+                    listValues: ["http://www.w3.org/ns/widgets"]
+                },
+                "xmlns:JIL": {
+                    attributeName: "xmlns:JIL",
+                    required: true,
+                    type: "list",
+                    listValues: ["http://www.jil.org/ns/widgets1.2"]
+                },
+                "xmlns:its": {
+                    attributeName: "xmlns:its",
+                    helpText: "Indicates Text Directionality can be used. According to W3C spec, this feature is at risk, therefore we don't currently validate this.",
+                    required: false,
+                    type: "string"
+                },
+                id: {
+                    attributeName: "id",
+                    required: true,
+                    type: "string"
+                },
+                version: {
+                    attributeName: "version",
+                    helpText: "Version must be in the following format: jil-rec-version-tag = major-version \".\" minor-version [\".\" version-desc]",
+                    required: true,
+                    type: "regex",
+                    regex: /^\d{1,2}\.\d{1,2}(\.[A-Za-z0-9]{1,10})?$/
+                },
+                height: {
+                    attributeName: "height",
+                    required: true,
+                    type: "integer"
+                },
+                width: {
+                    attributeName: "width",
+                    required: true,
+                    type: "integer"
+                },
+                viewmodes: {
+                    attributeName: "viewmodes",
+                    required: false,
+                    type: "list",
+                    listValues: ["floating", "fullscreen"]
+                },
+                "xml:lang": {
+                    attributeName: "xml:lang",
+                    required: false,
+                    type: "iso-language"
+                }
+            },
+            children: {
+                preference: {
+                    nodeName: "preference",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        name: {
+                            attributeName: "name",
+                            type: "string",
+                            required: true
+                        },
+                        value: {
+                            type: "string",
+                            attributeName: "value",
+                            required: false
+                        },
+                        readonly: {
+                            attributeName: "readonly",
+                            type: "boolean",
+                            required: false
+                        }
+                    }
+                },
+                name: {
+                    nodeName: "name",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "short": {
+                            attributeName: "short",
+                            type: "string",
+                            required: false
+                        },
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            type: "string",
+                            required: false,
+                            unique: true
+                        }
+                    }
+                },
+                description: {
+                    nodeName: "description",
+                    required: false,
+                    occurrence: 0,
+                    type: "string",
+                    attributes: {
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            type: "string",
+                            required: false,
+                            unique: true
+                        }
+                    }
+                },
+                icon: {
+                    nodeName: "icon",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        src: {
+                            attributeName: "src",
+                            type: "string",
+                            required: true
+                        },
+                        height: {
+                            attributeName: "height",
+                            required: false,
+                            type: "integer"
+                        },
+                        width: {
+                            attributeName: "width",
+                            required: false,
+                            type: "integer"
+                        },
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            type: "string",
+                            required: false,
+                            unique: true
+                        }
+                    }
+                },
+                author: {
+                    nodeName: "author",
+                    required: false,
+                    occurrence: 1,
+                    type: "string",
+                    attributes: {
+                        email: {
+                            attributeName: "email",
+                            type: "regex",
+                            required: false,
+                            regex: constants.REGEX.EMAIL
+                        },
+                        href: {
+                            attributeName: "href",
+                            type: "regex",
+                            required: false,
+                            regex: constants.REGEX.URL
+                        },
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            type: "string",
+                            required: false,
+                            unique: true
+                        }
+                    }
+                },
+                license: {
+                    nodeName: "license",
+                    required: false,
+                    occurrence: 1,
+                    type: "string",
+                    attributes: {
+                        href: {
+                            attributeName: "href",
+                            type: "regex",
+                            required: false,
+                            regex: constants.REGEX.URL
+                        },
+                        "xml:lang": {
+                            attributeName: "xml:lang",
+                            type: "string",
+                            required: false,
+                            unique: true
+                        }
+                    }
+                },
+                content: {
+                    nodeName: "content",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        src: {
+                            attributeName: "src",
+                            type: "string",
+                            required: true
+                        },
+                        encoding: {
+                            attributeName: "encoding",
+                            type: "string",
+                            required: false
+                        },
+                        type: {
+                            attributeName: "type",
+                            type: "string",
+                            required: false
+                        }
+                    }
+                },
+                feature: {
+                    nodeName: "feature",
+                    required: false,
+                    occurrence: 0,
+                    attributes: {
+                        name: {
+                            attributeName: "name",
+                            type: "list",
+                            required: true,
+                            listValues: ["http://jil.org/jil/api/1.1/widget", "http://jil.org/jil/api/1.1.5/exception",
+                                            "http://jil.org/jil/api/1.1.5/exceptiontypes", "http://jil.org/jil/api/1.1/device",
+                                            "http://jil.org/jil/api/1.1/accountinfo", "http://jil.org/jil/api/1.1/deviceinfo",
+                                            "http://jil.org/jil/api/1.1.1/datanetworkinfo", "http://jil.org/jil/api/1.1/devicestateinfo",
+                                            "http://jil.org/jil/api/1.1/accelerometerinfo", "http://jil.org/jil/api/1.1/config",
+                                            "http://jil.org/jil/api/1.1.1/file", "http://jil.org/jil/api/1.1/positioninfo",
+                                            "http://jil.org/jil/api/1.1/powerinfo", "http://jil.org/jil/api/1.1.1/radioinfo",
+                                            "http://jil.org/jil/api/1.1.5/radiosignalsourcetypes", "http://jil.org/jil/api/1.1.5/applicationtypes",
+                                            "http://jil.org/jil/api/1.1/messaging", "http://jil.org/jil/api/1.1/account",
+                                            "http://jil.org/jil/api/1.1/attachment", "http://jil.org/jil/api/1.1/message",
+                                            "http://jil.org/jil/api/1.1.4/messagefoldertypes", "http://jil.org/jil/api/1.1/messagequantities",
+                                            "http://jil.org/jil/api/1.1/messagetypes", "http://jil.org/jil/api/1.1/multimedia",
+                                            "http://jil.org/jil/api/1.1/audioplayer", "http://jil.org/jil/api/1.1.2/camera",
+                                            "http://jil.org/jil/api/1.1.2/videoplayer", "http://jil.org/jil/api/1.1.1/pim",
+                                            "http://jil.org/jil/api/1.1/addressbookitem", "http://jil.org/jil/api/1.1/calendaritem",
+                                            "http://jil.org/jil/api/1.1/eventrecurrencetypes", "http://jil.org/jil/api/1.1.1/telephony",
+                                            "http://jil.org/jil/api/1.1/callrecord", "http://jil.org/jil/api/1.1.1/callrecordtypes",
+                                            "http://jil.org/jil/api/1.1.1/widgetmanager"]
+                        },
+                        required: {
+                            attributeName: "required",
+                            type: "boolean",
+                            required: false
+                        }
+                    }
+                },
+                "JIL:maximum_display_mode": {
+                    nodeName: "JIL:maximum_display_mode",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        height: {
+                            attributeName: "height",
+                            type: "integer",
+                            required: false
+                        },
+                        width: {
+                            attributeName: "width",
+                            type: "integer",
+                            required: false
+                        }
+                    }
+                },
+                "JIL:update": {
+                    nodeName: "JIL:update",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        href: {
+                            attributeName: "href",
+                            type: "regex",
+                            required: true,
+                            regex: constants.REGEX.URL
+                        },
+                        period: {
+                            attributeName: "period",
+                            helpText: "Possible values for the period attribute are: 0, 1, 2, 3 meaning: every time the widget is opened in maximum display mode, every day, every week, every month; respectivly",
+                            type: "list",
+                            required: true,
+                            listValues: ["0", "1", "2", "3"]
+                        }
+                    }
+                },
+                "JIL:access": {
+                    nodeName: "JIL:access",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        network: {
+                            attributeName: "network",
+                            type: "boolean",
+                            required: false
+                        },
+                        localfs: {
+                            attributeName: "localfs",
+                            type: "boolean",
+                            required: false
+                        },
+                        remote_scripts: {
+                            attributeName: "remote_scripts",
+                            type: "boolean",
+                            required: false
+                        }
+                    }
+                },
+                "JIL:billing": {
+                    nodeName: "JIL:billing",
+                    required: false,
+                    occurrence: 1,
+                    attributes: {
+                        required: {
+                            attributeName: "required",
+                            type: "boolean",
+                            required: true
+                        }
+                    }
+                }
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/platform/wac/1.0/AddressBookItem', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    db = require('ripple/db'),
+    constants = require('ripple/constants'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes');
+
+function _validateArgs(min, max, len) {
+    utils.validateNumberOfArguments(min, max, len,
+        ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception());
+}
+
+function _validateType(arg, argType) {
+    utils.validateArgumentType(arg, argType,
+        ExceptionTypes.INVALID_PARAMETER,  "argument of wrong type provided",
+        new Exception());
+}
+
+module.exports = function () {
+    function _throwUnsupportedException(method) {
+        exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
+    }
+
+    this.addressBookItemId = undefined;
+    this.fullName = undefined;
+    this.mobilePhone = undefined;
+    this.homePhone = undefined;
+    this.workPhone = undefined;
+    this.eMail = undefined;
+    this.company = undefined;
+    this.title = undefined;
+    this.address = undefined;
+
+    this.setAttributeValue = function (attribute, value) {
+        _validateArgs(2, 2, arguments.length);
+        _validateType(attribute, "string");
+        this[attribute] = value;
+    };
+    this.setAddressGroupNames = function (groups) {
+        _throwUnsupportedException("PIM.AddressBookItem.setAddressGroupNames");
+    };
+    this.getAttributeValue = function (attribute) {
+        _validateArgs(1, 1, arguments.length);
+        _validateType(attribute, "string");
+        return this[attribute];
+    };
+    this.getAddressGroupNames = function () {
+        _throwUnsupportedException("PIM.AddressBookItem.getAddressGroupNames");
+    };
+    this.getAvailableAttributes = function () {
+        return utils.reduce(this, function (attributes, value, key) {
+            if (typeof(value) !== 'function') {
+                attributes.push(key);
+            }
+            return attributes;
+        }, []).sort();
+    };
+    this.update = function () {
+        var items = db.retrieveObject(constants.PIM.ADDRESS_LIST_KEY),
+            that = this,
+            itemIndex = items.reduce(function (current, value, i) {
+                return value.addressBookItemId === that.addressBookItemId ?
+                    i : current;
+            }, -1);
+
+        if (itemIndex >= 0) {
+            items[itemIndex] = this;
+            db.saveObject(constants.PIM.ADDRESS_LIST_KEY, items);
+        }
+        else {
+            exception.raise(ExceptionTypes.INVALID_PARAMETER, "Address Book Item not found: " + (this.addressBookItemId || ""), new Exception());
+        }
+
+    };
+};
+
+});
+require.define('ripple/platform/wac/1.0/spec', function (require, module, exports) {
+module.exports = {
+
+    id: "wac",
+    version: "1.0",
+    name: "WAC",
+    type: "plaform",
+
+    persistencePrefix: "wac-",
+
+    config: require('ripple/platform/wac/1.0/spec/config'),
+    device: require('ripple/platform/wac/1.0/spec/device'),
+    ui: require('ripple/platform/wac/1.0/spec/ui'),
+    events: require('ripple/platform/wac/1.0/spec/events'),
+
+    objects: {
+        navigator: {
+            path: "w3c/1.0/navigator"
+        },
+        WidgetManager: {
+            path: "wac/1.0/WidgetManager",
+            feature: "http://jil.org/jil/api/1.1.1/widgetmanager"
+        },
+        Widget: {
+            path: "wac/1.0/Widget",
+            feature: "http://jil.org/jil/api/1.1/widget",
+            children: {
+                Device: {
+                    path: "wac/1.0/Device",
+                    feature: "http://jil.org/jil/api/1.1/device",
+                    children: {
+                        AccountInfo: {
+                            path: "wac/1.0/AccountInfo",
+                            feature: "http://jil.org/jil/api/1.1/accountinfo"
+                        },
+                        ApplicationTypes: {
+                            path: "wac/1.0/ApplicationTypes",
+                            feature: "http://jil.org/jil/api/1.1.5/applicationtypes"
+                        },
+                        DataNetworkInfo: {
+                            path: "wac/1.0/DataNetworkInfo",
+                            feature: "http://jil.org/jil/api/1.1.1/datanetworkinfo",
+                            children: {
+                                DataNetworkConnectionTypes: {
+                                    path: "wac/1.0/DataNetworkConnectionTypes"
+                                }
+                            }
+                        },
+                        DeviceInfo: {
+                            path: "wac/1.0/DeviceInfo",
+                            feature: "http://jil.org/jil/api/1.1/deviceinfo"
+                        },
+                        DeviceStateInfo: {
+                            path: "wac/1.0/DeviceStateInfo",
+                            feature: "http://jil.org/jil/api/1.1/devicestateinfo",
+                            children: {
+                                Config: {
+                                    path: "wac/1.0/Config",
+                                    feature: "http://jil.org/jil/api/1.1/config"
+                                },
+                                AccelerometerInfo: {
+                                    path: "wac/1.0/AccelerometerInfo",
+                                    feature: "http://jil.org/jil/api/1.1/accelerometerinfo"
+                                }
+                            }
+                        },
+                        File: {
+                            path: "wac/1.0/File",
+                            feature: "http://jil.org/jil/api/1.1.1/file"
+                        },
+                        PositionInfo: {
+                            path: "wac/1.0/PositionInfo",
+                            feature: "http://jil.org/jil/api/1.1/positioninfo"
+                        },
+                        RadioInfo: {
+                            path: "wac/1.0/RadioInfo",
+                            feature: "http://jil.org/jil/api/1.1.1/radioinfo",
+                            children: {
+                                RadioSignalSourceTypes: {
+                                    path: "wac/1.0/RadioSignalSourceTypes",
+                                    feature: "http://jil.org/jil/api/1.1.5/radiosignalsourcetypes"
+                                }
+                            }
+                        },
+                        PowerInfo: {
+                            path: "wac/1.0/PowerInfo",
+                            feature: "http://jil.org/jil/api/1.1/powerinfo"
+                        }
+                    }
+                },
+                ExceptionTypes: {
+                    path: "wac/1.0/ExceptionTypes",
+                    feature: "http://jil.org/jil/api/1.1.5/exceptiontypes"
+                },
+                Exception: {
+                    path: "wac/1.0/Exception",
+                    feature: "http://jil.org/jil/api/1.1.5/exception"
+                },
+                Multimedia: {
+                    path: "wac/1.0/Multimedia",
+                    feature: "http://jil.org/jil/api/1.1/multimedia",
+                    children: {
+                        Camera: {
+                            path: "wac/1.0/Camera",
+                            feature: "http://jil.org/jil/api/1.1.2/camera"
+                        },
+                        AudioPlayer: {
+                            path: "wac/1.0/AudioPlayer",
+                            feature: "http://jil.org/jil/api/1.1/audioplayer"
+                        },
+                        VideoPlayer: {
+                            path: "wac/1.0/VideoPlayer",
+                            feature: "http://jil.org/jil/api/1.1.2/videoplayer"
+                        }
+                    }
+                },
+                Telephony: {
+                    path: "wac/1.0/Telephony",
+                    feature: "http://jil.org/jil/api/1.1.1/telephony",
+                    children: {
+                        CallRecord: {
+                            path: "wac/1.0/CallRecord",
+                            feature: "http://jil.org/jil/api/1.1/callrecord"
+                        },
+                        CallRecordTypes: {
+                            path: "wac/1.0/CallRecordTypes",
+                            feature: "http://jil.org/jil/api/1.1.1/callrecordtypes"
+                        }
+                    }
+                },
+                PIM: {
+                    path: "wac/1.0/PIM",
+                    feature: "http://jil.org/jil/api/1.1.1/pim",
+                    children: {
+                        AddressBookItem: {
+                            path: "wac/1.0/AddressBookItem",
+                            feature: "http://jil.org/jil/api/1.1/addressbookitem"
+                        },
+                        CalendarItem: {
+                            path: "wac/1.0/CalendarItem",
+                            feature: "http://jil.org/jil/api/1.1/calendaritem"
+                        },
+                        EventRecurrenceTypes: {
+                            path: "wac/1.0/EventRecurrenceTypes",
+                            feature: "http://jil.org/jil/api/1.1/eventrecurrencetypes"
+                        }
+                    }
+                },
+                Messaging: {
+                    path: "wac/1.0/Messaging",
+                    feature: "http://jil.org/jil/api/1.1/messaging",
+                    children: {
+                        Account: {
+                            path: "wac/1.0/Account",
+                            feature: "http://jil.org/jil/api/1.1/account"
+                        },
+                        Attachment: {
+                            path: "wac/1.0/Attachment",
+                            feature: "http://jil.org/jil/api/1.1/attachment"
+                        },
+                        Message: {
+                            path: "wac/1.0/Message",
+                            feature: "http://jil.org/jil/api/1.1/message"
+                        },
+                        MessageFolderTypes: {
+                            path: "wac/1.0/MessageFolderTypes",
+                            feature: "http://jil.org/jil/api/1.1.4/messagefoldertypes"
+                        },
+                        MessageQuantities: {
+                            path: "wac/1.0/MessageQuantities",
+                            feature: "http://jil.org/jil/api/1.1/messagequantities"
+                        },
+                        MessageTypes: {
+                            path: "wac/1.0/MessageTypes",
+                            feature: "http://jil.org/jil/api/1.1/messagetypes"
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+};
+
+});
+require.define('ripple/platform/wac/1.0/Widget', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    _console = require('ripple/console'),
+    app = require('ripple/app'),
+    platform = require('ripple/platform'),
+    exception = require('ripple/exception'),
+    ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
+    Exception = require('ripple/platform/wac/1.0/Exception'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    _self;
+
+event.on("ScreenChangeDimensions", function (height, width) {
+    try {
+        // TODO: are these per spec to call?
+        if (typeof app.onMaximize === 'function') {
+            app.onMaximize();
+        }
+        if (typeof app.onRestore === 'function') {
+            app.onRestore();
+        }
+        _console.log("called Widget.onRestore and Widget.onMaximize callback function");
+    }
+    catch (e) {
+        exception.handle(e, false);
+    }
+});
+
+event.on("WidgetWakeup", function () {
+    if (_self.onWakeup) {
+        _self.onWakeup();
+    }
+});
+
+event.on("WidgetMaximize", function () {
+    if (_self.onMaximize) {
+        _self.onMaximize();
+    }
+});
+
+event.on("WidgetFocus", function () {
+    if (_self.onFocus) {
+        _self.onFocus();
+    }
+});
+
+event.on("WidgetRestore", function () {
+    if (_self.onRestore) {
+        _self.onRestore();
+    }
+});
+
+_self = {
+    onWakeup: undefined,
+    onMaximize: undefined,
+    onFocus: undefined,
+    onRestore: undefined,
+
+    openURL: function (url) {
+        window.open(url);
+    },
+
+    setPreferenceForKey: function (value, key) {
+
+        utils.validateNumberOfArguments(1, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "setPreferenceForKey invalid number of paramters", new Exception());
+        utils.validateArgumentType(key, "string", ExceptionTypes.INVALID_PARAMETER, "setPreferenceForKey invalid parameter! Key:" +
+            key + ", Value: " + value, new Exception());
+
+        var msg = "",
+            prefix;
+        if (app.isPreferenceReadOnly(key)) {
+            msg += "Cannot modify a read only preference. Preference key: " + key;
+        }
+        else {
+            prefix = platform.getPersistencePrefix();
+            if (value === null) {
+                msg += "deleting preference " + key;
+                db.remove(key, prefix);
+            }
+            else {
+                msg += "setting preference " + key + " == " + value;
+                utils.validateArgumentType(value, "string", ExceptionTypes.INVALID_PARAMETER, msg, new Exception());
+                db.save(key, value, prefix);
+            }
+        }
+
+
+        _console.log(msg);
+
+        // Trigger storageUpdatedEvent
+        event.trigger("StorageUpdatedEvent");
+
+    },
+
+    // return value or undefined
+    preferenceForKey: function (key) {
+
+        utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "preferenceForKey invalid number of parameters", new Exception());
+        utils.validateArgumentType(key, "string", ExceptionTypes.INVALID_PARAMETER, "preferenceForKey invalid paramters", new Exception());
+
+        var prefix = platform.getPersistencePrefix(),
+            value = db.retrieve(key, prefix);
+
+        if (!value && value !== "") {
+            value = undefined;
+        }
+
+        _console.log("retrieving preference " + key + " == " + value);
+
+        return value;
+
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/spec', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+/*  
+    "phonegap": {"1.0": require('ripple/platform/phonegap/1.0/spec')},
+    "webworks.handset": {"2.0.0": require('ripple/platform/webworks.handset/2.0.0/spec')},
+    "webworks.tablet": {"2.0.0": require('ripple/platform/webworks.tablet/2.0.0/spec')},
+    "web": {"default": require('ripple/platform/web/default/spec')},
+*/
+//    "wac": {"2.0": require('ripple/platform/wac/2.0/spec')},
+    "tizen": {"1.0": require('ripple/platform/tizen/1.0/spec')}
+};
+
+});
+require.define('ripple/platform/web/default/device', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+window.addEventListener("load", function () {
+    var event = require('ripple/event');
+
+    event.on("HardwareKey", function (key) {
+        event.trigger("HardwareKeyDefault", [key]);
+    });
+
+    //HACK: Remove this guy from namespace since we are just hacking this in as a bootstrapper
+    delete window.device;
+});
+
+});
+require.define('ripple/platform/web/default/spec/ui', function (require, module, exports) {
+module.exports = {
+    plugins: [
+        "accelerometer",
+        "geoView"
+    ]
+};
+
+});
+require.define('ripple/platform/web/default/spec', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = {
+
+    id: "web",
+    version: "default",
+    name: "Mobile Web",
+
+    ui: require('ripple/platform/web/default/spec/ui'),
+    device: {},
+
+    persistencePrefix: "tinyhippos-",
+
+    objects: {
+        Coordinates: {
+            path: "w3c/1.0/Coordinates"
+        },
+        Position: {
+            path: "w3c/1.0/Position"
+        },
+        PositionError: {
+            path: "w3c/1.0/PositionError"
+        },
+        navigator: {
+            path: "w3c/1.0/navigator",
+            children: {
+                geolocation: {
+                    path: "w3c/1.0/geolocation"
+                }
+            }
+        },
+        device: {
+            path: "web/default/device"
+        }
+    },
+};
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/server/dialog', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    devices = require('ripple/devices'),
+    ui = require('ripple/ui'),
+    utils = require('ripple/utils'),
+    isDialogVisible = false,
+    visibleDialogArgs,
+    _self;
+
+function closeDialog() {
+    var buttonsDiv = document.getElementById("dialog-buttons"),
+        messageDiv = document.getElementById("dialog-message");
+
+    ui.hideOverlay("dialog-window", function (dialog) {
+        buttonsDiv.innerHTML = "";
+        messageDiv.innerHTML = "";
+        isDialogVisible = false;
+    });
+}
+
+event.on("LayoutChanged", function () {
+    if (isDialogVisible) {
+        closeDialog();
+        //Used to resize dialog on orientation change
+        _self.ask(visibleDialogArgs);
+    }
+});
+
+_self = {
+
+    ask: function (args, post, baton) {
+        if (!args) {
+            throw ("No arguments provided");
+        } else if (!args.buttons || !args.message) {
+            throw ("Invalid arguments");
+        }
+        baton.take();
+        visibleDialogArgs = args;
+
+        ui.showOverlay("dialog-window", function (dialog) {
+            var container = document.getElementById(constants.COMMON.VIEWPORT_CONTAINER),
+                height = window.getComputedStyle(container, null).getPropertyValue("height"),
+                width = window.getComputedStyle(container, null).getPropertyValue("width"),
+                sizeDiv = document.getElementById("dialog-wrapper"),
+                positionDiv = document.getElementById("dialog-window"),
+                titleDiv = document.getElementById("dialog-title"),
+                buttonsDiv = document.getElementById("dialog-buttons"),
+                messageDiv = document.getElementById("dialog-message"),
+                position, size;
+
+            if (!messageDiv || !buttonsDiv) {
+                return;
+            }
+
+            dialog.setAttribute("style", "display:-webkit-box;height:" + height + "; width:" + width + ";");
+
+            position = "overlay-dialog";
+            size = "overlay-dialog-wrapper";
+
+            if (args.settings && args.settings.position) {
+                position += " overlay-dialog-" + args.settings.position;
+            }
+
+            if (args.settings && args.settings.size) {
+                size += " overlay-dialog-wrapper-" + args.settings.size;
+            }
+
+            positionDiv.setAttribute("class", position);
+            sizeDiv.setAttribute("class", size);
+
+            titleDiv.innerHTML = args.settings && args.settings.title ? args.settings.title : "";
+            messageDiv.innerHTML = args.message;
+            isDialogVisible = true;
+
+            args.buttons.forEach(function (button) {
+                var buttonElement = utils.createElement("input", {
+                    "type": "button",
+                    "value": button
+                });
+                buttonElement.addEventListener("click", function () {
+                    var buttonIndex = args.buttons.indexOf(button);
+                    closeDialog();
+                    baton.pass({code: 1, data: buttonIndex});
+                });
+                buttonsDiv.appendChild(buttonElement);
+            });
+        }, true);
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/server/appEvent', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    _bg,
+    _fg,
+    _swipeDown,
+    _swipeStart,
+    _exit;
+
+event.on("AppRequestBackground", function () {
+    var baton = _bg;
+    _bg = null;
+    return baton && baton.pass({code: 1});
+});
+
+event.on("AppRequestForeground", function () {
+    var baton = _fg;
+    _fg = null;
+    return baton && baton.pass({code: 1});
+});
+
+event.on("AppSwipeDown", function () {
+    var baton = _swipeDown;
+    _swipeDown = null;
+    return baton && baton.pass({code: 1});
+});
+
+event.on("AppSwipeStart", function () {
+    var baton = _swipeStart;
+    _swipeStart = null;
+    return baton && baton.pass({code: 1});
+});
+
+module.exports = {
+    onBackground: function (get, post, baton) {
+        baton.take();
+        _bg = baton;
+        return {code: 1};
+    },
+
+    onForeground: function (get, post, baton) {
+        baton.take();
+        _fg = baton;
+        return {code: 1};
+    },
+
+    onSwipeDown: function (get, post, baton) {
+        baton.take();
+        _swipeDown = baton;
+        return {code: 1};
+    },
+
+    onSwipeStart: function (get, post, baton) {
+        baton.take();
+        _swipeStart = baton;
+        return {code: 1};
+    }
+};
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/server/app', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    app = require('ripple/app'),
+    _self;
+
+_self = {
+    event: require('ripple/platform/webworks.tablet/2.0.0/server/appEvent'),
+
+    exit: function () {
+        event.trigger("AppExit");
+        return {code: 1};
+    },
+
+    author: function () {
+        return {code: 1, data: app.getInfo().author};
+    },
+
+    authorEmail: function () {
+        return {code: 1, data: app.getInfo().authorEmail};
+    },
+
+    authorURL: function () {
+        return {code: 1, data: app.getInfo().authorURL};
+    },
+
+    copyright: function () {
+        return {code: 1, data: app.getInfo().copyright};
+    },
+
+    description: function () {
+        return {code: 1, data: app.getInfo().description};
+    },
+
+    id: function () {
+        return {code: 1, data: app.getInfo().id};
+    },
+
+    license: function () {
+        return {code: 1, data: app.getInfo().license};
+    },
+
+    licenseURL: function () {
+        return {code: 1, data: app.getInfo().licenseURL};
+    },
+
+    name: function () {
+        return {code: 1, data: app.getInfo().name};
+    },
+
+    version: function () {
+        return {code: 1, data: app.getInfo().version};
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/server/invoke', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var notifications = require('ripple/notifications'),
+    constants = require('ripple/constants'),
+    type = "normal",
+    name = {
+        "camera://": "Camera",
+        "camera://video": "Video Camera",
+        "map://": "Maps",
+        "http://": "Browser",
+        "music://": "Music",
+        "photos://": "Photos",
+        "videos://": "Videos",
+        "appworld://": "App World",
+        "update://": "Update"
+    };
+
+module.exports = {
+    invoke: function (opts) {
+        var app = name[opts.appType];
+        if (app === undefined && opts.appType && opts.appType.match(/^http/i)) {
+            app = "Browser";
+        }
+
+        notifications.openNotification(type,
+           "Requested to launch: " + app + " application.");
+        return {code: 1};
+    }
+};
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/server/identity', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var deviceSettings = require('ripple/deviceSettings');
+
+module.exports = {
+    PIN: function () {
+        return {code: 1, data: deviceSettings.retrieve("identity.PIN")};
+    }
+};
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/server/systemEvent', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    _onBatteryStateChange,
+    _onBatteryLevelChange,
+    _states = {
+        UNKNOWN: 0,
+        FULL: 1,
+        CHARGING: 2,
+        UNPLUGGED: 3
+    },
+    _battery = {
+        state: _states.UNKNOWN,
+        charging: null,
+        level: null
+    };
+
+function _getState() {
+    return _battery.level === 100 ? _states.FULL :
+           _battery.charging ? _states.CHARGING : _states.UNPLUGGED;
+}
+
+function _pass(baton, data) {
+    if (baton) {
+        baton.pass({code: 1, data: data});
+    }
+}
+
+event.on("DeviceBatteryStateChanged", function (charging) {
+    _battery.charging = charging;
+    _battery.state = _getState();
+    _pass(_onBatteryStateChange, _battery.state);
+});
+
+event.on("DeviceBatteryLevelChanged", function (level) {
+    level = parseInt(level, 10);
+
+    _battery.level = level;
+    _pass(_onBatteryLevelChange, level);
+
+    if (level === 100) {
+        _battery.state = _getState();
+        _pass(_onBatteryStateChange, _battery.state);
+    }
+});
+
+module.exports = {
+    deviceBatteryLevelChange: function (get, post, baton) {
+        baton.take();
+        _onBatteryLevelChange = baton;
+    },
+    deviceBatteryStateChange: function (get, post, baton) {
+        baton.take();
+        _onBatteryStateChange = baton;
+    }
+};
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/server', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    platform = "ripple/platform/webworks.tablet/2.0.0/server/",
+    core = "ripple/platform/webworks.core/2.0.0/server/",
+    systemEvent = require(platform + 'systemEvent'),
+    system = {};
+
+// ugh, thanks to the spec...
+system.event = systemEvent;
+utils.mixin(require(core + "system"), system);
+
+module.exports = {
+    blackberry: {
+        identity: require(platform + "identity"),
+        app: require(platform + "app"),
+        invoke: require(platform + "invoke"),
+        system: system,
+        ui: {
+            dialog: require(platform + "dialog")
+        },
+        io: {
+            dir: require(core + "io/dir"),
+            file: require(core + "io/file")
+        }
+    }
+};
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/XMLHttpRequest', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var xhr = require("ripple/platform/webworks.core/2.0.0/XMLHttpRequest");
+module.exports = xhr.create("ripple/platform/webworks.tablet/2.0.0/server");
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/client/BrowserArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.BrowserArguments ( url : String ,  [transport : blackberry.identity.Transport ] )
+module.exports = function (url, transport) {
+    return {
+        url: url
+    };
+};
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/client/dialog', function (require, module, exports) {
+/*\r
+ *  Copyright 2011 Research In Motion Limited.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
+    _uri = "blackberry/ui/dialog/",\r
+    _self;\r
+\r
+function getButtonsForDialogType(dialogType) {\r
+    switch (dialogType) {\r
+    case _self.D_OK:\r
+        return ["Ok"];\r
+    case _self.D_SAVE:\r
+        return ["Save", "Discard"];\r
+    case _self.D_DELETE:\r
+        return ["Delete", "Cancel"];\r
+    case _self.D_YES_NO:\r
+        return ["Yes", "No"];\r
+    case _self.D_OK_CANCEL:\r
+        return ["Ok", "Cancel"];\r
+    default:\r
+        throw new Error("Invalid dialog type: " + dialogType);\r
+    }\r
+}\r
+\r
+_self = {\r
+    customAskAsync: function (message, choices, callback, settings) {\r
+        return transport.call(_uri + "ask", {\r
+            async: true,\r
+            get: {\r
+                message: message,\r
+                buttons: choices,\r
+                settings: settings\r
+            }\r
+        }, function (response) {\r
+            if (callback) {\r
+                callback(response);\r
+            }\r
+        });\r
+    },\r
+\r
+    standardAskAsync: function (message, type, callback, settings) {\r
+        var choices = getButtonsForDialogType(type);\r
+        return transport.call(_uri + "ask", {\r
+            async: true,\r
+            get: {\r
+                message: message,\r
+                buttons: choices,\r
+                settings: settings\r
+            }\r
+        }, function (response) {\r
+            if (callback) {\r
+                callback(response);\r
+            }\r
+        });\r
+    }\r
+};\r
+\r
+_self.__defineGetter__("D_OK", function () {\r
+    return 0;\r
+});\r
+\r
+_self.__defineGetter__("D_SAVE", function () {\r
+    return 1;\r
+});\r
+\r
+_self.__defineGetter__("D_DELETE", function () {\r
+    return 2;\r
+});\r
+\r
+_self.__defineGetter__("D_YES_NO", function () {\r
+    return 3;\r
+});\r
+\r
+_self.__defineGetter__("D_OK_CANCEL", function () {\r
+    return 4;\r
+});\r
+\r
+_self.__defineGetter__("BOTTOM", function () {\r
+    return "bottomCenter";\r
+});\r
+\r
+_self.__defineGetter__("CENTER", function () {\r
+    return "middleCenter";\r
+});\r
+\r
+_self.__defineGetter__("TOP", function () {\r
+    return "topCenter";\r
+});\r
+\r
+_self.__defineGetter__("SIZE_FULL", function () {\r
+    return "full";\r
+});\r
+\r
+_self.__defineGetter__("SIZE_LARGE", function () {\r
+    return "large";\r
+});\r
+\r
+_self.__defineGetter__("SIZE_MEDIUM", function () {\r
+    return "medium";\r
+});\r
+\r
+_self.__defineGetter__("SIZE_SMALL", function () {\r
+    return "small";\r
+});\r
+\r
+_self.__defineGetter__("SIZE_TALL", function () {\r
+    return "tall";\r
+});\r
+\r
+module.exports = _self;\r
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/client/appEvent', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _callbacks = {},
+    _self;
+
+function _poll(evt, handler) {
+    _callbacks[evt] = handler;
+
+    transport.poll("blackberry/app/event/" + evt, {}, function () {
+        var func = _callbacks[evt];
+
+        if (func) {
+            func();
+        }
+
+        return !!func;
+    });
+}
+
+_self = {
+    onBackground: function (handler) {
+        _poll("onBackground", handler);
+    },
+
+    onForeground: function (handler) {
+        _poll("onForeground", handler);
+    },
+
+    onSwipeDown: function (handler) {
+        _poll("onSwipeDown", handler);
+    },
+
+    onSwipeStart: function (handler) {
+        _poll("onSwipeStart", handler);
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/client/app', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/app/",
+    _self;
+
+_self = {
+    exit: function () {
+        transport.call(_uri + "exit", {async: true});
+    }
+};
+
+_self.__defineGetter__("author", function () {
+    return transport.call(_uri + "author");
+});
+
+_self.__defineGetter__("authorEmail", function () {
+    return transport.call(_uri + "authorEmail");
+});
+
+_self.__defineGetter__("authorURL", function () {
+    return transport.call(_uri + "authorURL");
+});
+
+_self.__defineGetter__("copyright", function () {
+    return transport.call(_uri + "copyright");
+});
+
+_self.__defineGetter__("description", function () {
+    return transport.call(_uri + "description");
+});
+
+_self.__defineGetter__("id", function () {
+    return transport.call(_uri + "id");
+});
+
+_self.__defineGetter__("license", function () {
+    return transport.call(_uri + "license");
+});
+
+_self.__defineGetter__("licenseURL", function () {
+    return transport.call(_uri + "licenseURL");
+});
+
+_self.__defineGetter__("name", function () {
+    return transport.call(_uri + "name");
+});
+
+_self.__defineGetter__("version", function () {
+    return transport.call(_uri + "version");
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/client/io/dir', function (require, module, exports) {
+/*
+ * Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var dir = require('ripple/platform/webworks.core/2.0.0/client/io/dir'),
+    utils = require('ripple/utils'),
+    _self = {};
+
+utils.mixin({
+    appDirs: {
+        "app": {
+            "storage" : {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/data"
+            }
+        },
+        "shared": {
+            "bookmarks": {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/shared/bookmarks"
+            },
+            "books": {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/shared/books"
+            },
+            "camera": {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/shared/camera"
+            },
+            "documents": {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/shared/documents"
+            },
+            "downloads": {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/shared/downloads"
+            },
+            "misc": {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/shared/misc"
+            },
+            "music": {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/shared/music"
+            },
+            "photos": {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/shared/photos"
+            },
+            "print": {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/shared/print"
+            },
+            "videos": {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/shared/videos"
+            },
+            "voice": {
+                "path" : "file:///accounts/1000/appdata/emulatedapp/shared/voice"
+            }
+        }
+    }
+}, _self);
+
+utils.mixin(dir, _self);
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/client/invoke', function (require, module, exports) {
+/*\r
+ *  Copyright 2011 Research In Motion Limited.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+var _uri = "blackberry/invoke/invoke",\r
+    APP_TYPE = "appType",\r
+    APP_URL_CAMERA = "camera://",\r
+    APP_URL_CAMERA_VIDEO = "camera://video",\r
+    APP_URL_MAP = "map://",\r
+    APP_URL_MUSIC = "music://",\r
+    APP_URL_PHOTOS = "photos://",\r
+    APP_URL_VIDEOS = "videos://",\r
+    APP_URL_APPWORLD = "appworld://",\r
+    APP_URL_UPDATE = "update://",\r
+    APP_TYPE_ERROR = "appType not supported",\r
+    APP_BROWSER_ERROR = "Protocol specified in the url is not supported.",\r
+    transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
+    _self;\r
+\r
+_self = {\r
+    invoke: function (appType, args) {\r
+        var get = {};\r
+\r
+        switch (appType) {\r
+\r
+        //Camera\r
+        case 4:\r
+            if (!args || args.view === 1) {\r
+                get.appType = APP_URL_CAMERA_VIDEO;\r
+            } else {\r
+                get.appType = APP_URL_CAMERA;\r
+            }\r
+            break;\r
+\r
+        //Maps\r
+        case 5:\r
+            get.appType = APP_URL_MAP;\r
+            break;\r
+\r
+        //Browser\r
+        case 11:\r
+\r
+            if (!args) {\r
+                get.appType = "http://";\r
+            }\r
+            else {\r
+                get.appType = args.url.split("://");\r
+\r
+                if (get.appType.length === 1) {\r
+                    get.appType = "http://" + get.appType[0];\r
+                }\r
+                else if (get.appType.length === 2) {\r
+                    if (get.appType[0].indexOf("http") !== 0) {\r
+                        throw APP_BROWSER_ERROR;\r
+                    }\r
+                    else {\r
+                        get.appType = args.url;\r
+                    }\r
+                }\r
+            }\r
+            break;\r
+\r
+        //Music\r
+        case 13:\r
+            get.appType = APP_URL_MUSIC;\r
+            break;\r
+\r
+        //Photos\r
+        case 14:\r
+            get.appType = APP_URL_PHOTOS;\r
+            break;\r
+\r
+        //Videos\r
+        case 15:\r
+            get.appType = APP_URL_VIDEOS;\r
+            break;\r
+\r
+        //AppWorld\r
+        case 16:\r
+            get.appType = APP_URL_APPWORLD;\r
+            break;\r
+\r
+        //Update\r
+        case 17:\r
+            get.appType = APP_URL_UPDATE;\r
+            break;\r
+\r
+        default:\r
+            throw APP_TYPE_ERROR;\r
+        }\r
+\r
+        transport.call(_uri, {\r
+            get: get,\r
+            async: true\r
+        });\r
+    }\r
+};\r
+\r
+_self.__defineGetter__("APP_CAMERA", function () {\r
+    return 4;\r
+});\r
+_self.__defineGetter__("APP_MAPS", function () {\r
+    return 5;\r
+});\r
+_self.__defineGetter__("APP_BROWSER", function () {\r
+    return 11;\r
+});\r
+_self.__defineGetter__("APP_MUSIC", function () {\r
+    return 13;\r
+});\r
+_self.__defineGetter__("APP_PHOTOS", function () {\r
+    return 14;\r
+});\r
+_self.__defineGetter__("APP_VIDEOS", function () {\r
+    return 15;\r
+});\r
+_self.__defineGetter__("APP_APPWORLD", function () {\r
+    return 16;\r
+});\r
+\r
+module.exports = _self;\r
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/client/identity', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    _uri = "blackberry/identity/",
+    _self = {};
+
+_self.__defineGetter__("PIN", function () {
+    return transport.call(_uri + "PIN");
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/client/CameraArguments', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//blackberry.invoke.CameraArguments ( )
+var _self = function () {
+    return {
+        //readwrite  property  Number   view
+        view: 0
+    };
+};
+
+//const Number  VIEW_CAMERA  = 0
+_self.__defineGetter__("VIEW_CAMERA", function () {
+    return 0;
+});
+//const Number  VIEW_RECORDER  = 1
+_self.__defineGetter__("VIEW_RECORDER", function () {
+    return 1;
+});
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/client/systemEvent', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    api = "blackberry/system/event/";
+
+function _poll(evt, handler) {
+    transport.poll(api + evt, {}, function (data, response) {
+        if (handler) {
+            handler(data);
+        }
+        return !!handler;
+    });
+}
+
+module.exports = {
+    deviceBatteryLevelChange: function (handler) {
+        _poll("deviceBatteryLevelChange", handler);
+    },
+    deviceBatteryStateChange: function (handler) {
+        _poll("deviceBatteryStateChange", handler);
+    }
+};
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/spec/events', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    events = require('ripple/platform/webworks.core/2.0.0/spec/events');
+
+_self = {
+    "app.event.onSwipeDown": {
+        callback: function () {
+            event.trigger("AppSwipeDown");
+        }
+    },
+    "app.event.onSwipeStart": {
+        callback: function () {
+            event.trigger("AppSwipeStart");
+        }
+    }
+};
+
+utils.mixin(events, _self);
+
+module.exports = _self;
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/spec/device', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event');
+
+module.exports = {
+    "transports": {
+        "TCPCellular": {
+            "name": "Cellular TCP",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        },
+        "WAP": {
+            "name": "WAP",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            }
+        },
+        "WAP2": {
+            "name": "WAP 2.0",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            }
+        },
+        "MDS": {
+            "name": "MDS",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        },
+        "BISB": {
+            "name": "BIS B",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        },
+        "Unite": {
+            "name": "Unite!",
+            "control": {
+                "type": "checkbox",
+                "value": false
+            }
+        },
+        "TCPWifi": {
+            "name": "Wifi TCP",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        }
+    },
+    "identity": {
+        "PIN": {
+            "name": "PIN",
+            "control": {
+                "type": "text",
+                "value": "43A8C489"
+            }
+        }
+    },
+    "battery": {
+        "state": {
+            "name": "Handset is Charging",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "callback": function (setting) {
+                event.trigger("DeviceBatteryStateChanged", [setting]);
+            }
+        },
+        "level":  {
+            "name": "Charge Level (% remaining)",
+            "control": {
+                "type": "select",
+                "value": 100
+            },
+            "options": (function () {
+                var i,
+                    optionList = {};
+
+                for (i = 0; i <= 100; i++) {
+                    optionList[i] = i;
+                }
+
+                return optionList;
+            }()),
+            "callback": function (setting) {
+                event.trigger("DeviceBatteryLevelChanged", [setting]);
+            }
+        }
+    },
+    "system": {
+        "isMassStorageActive": {
+            "name": "Mass Storage Is Connected",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            }
+        },
+        "hasDataCoverage": {
+            "name": "Has Data Coverage",
+            "control": {
+                "type": "checkbox",
+                "value": true
+            },
+            "callback": function (setting) {
+                event.trigger("CoverageChange");
+            }
+        },
+        "network": {
+            "name": "Data Network",
+            "control": {
+                "type": "select",
+                "value": "3GPP"
+            },
+            "options": {
+                "3GPP" : "3GPP",
+                "CDMA": "CDMA",
+                "iDEN": "iDEN",
+                "Wi-Fi": "Wi-Fi"
+            },
+            "callback": function (setting) {
+                event.trigger("CoverageChange");
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/spec/ui', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    plugins: [
+        "accelerometer",
+        "deviceSettings",
+        "geoView",
+        "platformEvents",
+        "widgetConfig"
+    ]
+};
+
+});
+require.define('ripple/platform/webworks.tablet/2.0.0/spec', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+
+    id: "webworks.tablet",
+    version: "2.0.0",
+    name: "WebWorks-TabletOS",
+
+    persistencePrefix: "rim-tablet-",
+
+    ui: require('ripple/platform/webworks.tablet/2.0.0/spec/ui'),
+    device: require('ripple/platform/webworks.tablet/2.0.0/spec/device'),
+    config: require('ripple/platform/webworks.core/2.0.0/spec/config'),
+    events: require('ripple/platform/webworks.tablet/2.0.0/spec/events'),
+
+    objects: {
+        XMLHttpRequest: {
+            path: "webworks.tablet/2.0.0/XMLHttpRequest"
+        },
+        Coordinates: {
+            path: "w3c/1.0/Coordinates"
+        },
+        Position: {
+            path: "w3c/1.0/Position"
+        },
+        PositionError: {
+            path: "w3c/1.0/PositionError"
+        },
+        navigator: {
+            path: "w3c/1.0/navigator",
+            children: {
+                geolocation: {
+                    path: "w3c/1.0/geolocation"
+                }
+            }
+        },
+        blackberry: {
+            children: {
+                transport: {
+                    path: "webworks.core/2.0.0/client/transport"
+                },
+                events: {
+                    path: "webworks.core/2.0.0/client/events"
+                },
+                app: {
+                    path: "webworks.tablet/2.0.0/client/app",
+                    feature: "blackberry.app",
+                    children: {
+                        event: {
+                            path: "webworks.tablet/2.0.0/client/appEvent",
+                            feature: "blackberry.app.event"
+                        }
+                    }
+                },
+                invoke: {
+                    path: "webworks.tablet/2.0.0/client/invoke",
+                    feature: "blackberry.invoke",
+                    children: {
+                        BrowserArguments: {
+                            path: "webworks.tablet/2.0.0/client/BrowserArguments",
+                            feature: "blackberry.invoke.BrowserArguments"
+                        },
+                        CameraArguments: {
+                            path: "webworks.tablet/2.0.0/client/CameraArguments",
+                            feature: "blackberry.invoke.CameraArguments"
+                        }
+                    }
+                },
+                identity: {
+                    path: "webworks.tablet/2.0.0/client/identity",
+                    feature: "blackberry.identity"
+                },
+                system: {
+                    path: "webworks.core/2.0.0/client/system",
+                    children: {
+                        event: {
+                            path: "webworks.tablet/2.0.0/client/systemEvent"
+                        }
+                    }
+                },
+                ui: {
+                    children: {
+                        dialog: {
+                            path: "webworks.tablet/2.0.0/client/dialog",
+                            feature: "blackberry.ui.dialog"
+                        }
+                    }
+                },
+                utils: {
+                    path: "webworks.core/2.0.0/client/utils",
+                    feature: "blackberry.utils"
+                },
+                io: {
+                    children: {
+                        dir: {
+                            path: "webworks.tablet/2.0.0/client/io/dir",
+                            feature: "blackberry.io.dir"
+                        },
+                        file: {
+                            path: "webworks.core/2.0.0/client/io/file",
+                            feature: "blackberry.io.file"
+                        }
+                    }
+                }
+            }
+        }
+    }
+};
+
+});
+require.define('ripple/omgwtf', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    db = require('ripple/db'),
+    _loaded = false,
+    _self;
+
+function _delay(action) {
+    window.setTimeout(function () {
+        if (!_loaded) {
+            if (jQuery(".first-run-window").is(":visible")) {
+                _delay(action);
+            } else {
+                action();
+            }
+        }
+    }, 10000);
+}
+
+function _hide() {
+    jQuery(".error-window").css({display: 'none'});
+    jQuery(".error-dialog").css({display: 'none'});
+}
+
+function _show() {
+    jQuery(".error-window").css({display: 'block'});
+
+    jQuery(".error-dialog").css({
+        display: 'block',
+        left: (jQuery(document).width() / 2) - 277 + "px"
+    });
+
+    jQuery("#error-wait").click(function () {
+        _hide();
+        _delay(_show);
+    });
+
+    jQuery("#error-panic").click(function () {
+        db.removeAll(null, function () {
+            localStorage.clear();
+            location.reload();
+        });
+    });
+}
+
+_delay(_show);
+
+_self = {
+    initialize: function (previous, baton) {
+        event.on("TinyHipposLoaded", function () {
+            _loaded = true;
+        });
+    },
+    show: _show,
+    hide: _hide
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/accelerometer', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    event = require('ripple/event'),
+    Rotation = require('ripple/platform/w3c/1.0/Rotation'),
+    Acceleration = require('ripple/platform/w3c/1.0/Acceleration'),
+    _motion = {
+        acceleration: new Acceleration(0, 0, 0),
+        accelerationIncludingGravity: new Acceleration(0, 0, -9.81),
+        rotationRate: new Rotation(0, 0, 0),
+        orientation: new Rotation(0, 0, 0),
+        timestamp: new Date().getTime()
+    };
+
+function _validateAccelerometerInfo(x, y, z) {
+    return !(isNaN(x) || isNaN(y) || isNaN(z));
+}
+
+_self = {
+    getInfo: function () {
+        return utils.copy(_motion);
+    },
+
+    setInfo: function (e) {
+        var triggerDeviceMotion = false,
+            triggerDeviceOrientation = false;
+
+        if (e.x !== undefined && e.y !== undefined && e.z !== undefined) {
+            _motion = {
+                acceleration: new Acceleration(e.x, e.y, e.z),
+                accelerationIncludingGravity: new Acceleration(e.x, e.y, e.z),
+                rotationRate: new Rotation(0, 0, 0),
+                orientation: new Rotation(e.alpha, e.beta, e.gamma),
+                timestamp: new Date().getTime()
+            };
+            triggerDeviceMotion = true;
+            triggerDeviceOrientation = true;
+        }
+        else {
+            _motion = {
+                acceleration: new Acceleration(0, 0, 0),
+                accelerationIncludingGravity: new Acceleration(0, 0, -9.81),
+                rotationRate: new Rotation(0, 0, 0),
+                orientation: new Rotation(0, 0, 0),
+                timestamp: new Date().getTime()
+            };
+        }
+
+        if (triggerDeviceMotion) {
+            event.trigger("DeviceMotionEvent", [_motion]);
+        }
+
+        if (triggerDeviceOrientation) {
+            event.trigger("DeviceOrientationEvent", [_motion]);
+        }
+
+        event.trigger("AccelerometerInfoChangedEvent", [_motion]);
+    },
+
+    shake: function (shakeXtimes) {
+        var id,
+            count = 1,
+            stopCount = shakeXtimes || 17,
+            oldX = _motion.accelerationIncludingGravity.x;
+
+
+        id = setInterval(function () {
+            var freq = 1,
+                amp = 30,
+                value = Math.round(amp * Math.sin(freq * count * (180 / Math.PI)) * 100) / 100;
+
+            if (count > stopCount) {
+                _motion.acceleration.x = oldX;
+                _motion.accelerationIncludingGravity.x = oldX;
+                event.trigger("AccelerometerInfoChangedEvent", [_motion]);
+                clearInterval(id);
+                return;
+            }
+
+            _motion.acceleration.x = value;
+            _motion.accelerationIncludingGravity.x = value;
+
+            event.trigger("AccelerometerInfoChangedEvent", [_motion]);
+
+            count++;
+
+        }, 80);
+
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/db', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    _db,
+    utils = require('ripple/utils'),
+    constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    _cache = {};
+
+function _validateAndSetPrefix(prefix) {
+    if (prefix) {
+        utils.validateArgumentType(prefix, "string");
+    }
+
+    return prefix || constants.COMMON.PREFIX;
+}
+
+function _createKey(key, prefix) {
+    return _validateAndSetPrefix(prefix) + key;
+}
+
+function _createItem(key, value, prefix) {
+    return {
+        id: _createKey(key, prefix),
+        key: key,
+        value: value,
+        prefix: _validateAndSetPrefix(prefix)
+    };
+}
+
+function _save(key, value, prefix, callback) {
+    var item = _createItem(key, value, prefix);
+    _cache[item.id] = item;
+
+    _db.transaction(function (tx) {
+        tx.executeSql('REPLACE INTO persistence (id, key, value, prefix) VALUES (?, ?, ?, ?)', [item.id, item.key, item.value, item.prefix], function () {
+            return callback && callback();
+        });
+    });
+}
+
+function _retrieve(key, prefix) {
+    var item = _cache[_createKey(key, prefix)];
+    return item ? item.value : undefined;
+}
+
+function _retrieveAll(prefix, callback) {
+    var result = {};
+
+    if (prefix) {
+        utils.forEach(_cache, function (value, key) {
+            if (value.prefix === prefix) {
+                result[value.key] = value.value;
+            }
+        });
+    }
+
+    callback.apply(null, [result]);
+}
+
+function _remove(key, prefix, callback) {
+    delete _cache[_createKey(key, prefix)];
+
+    _db.transaction(function (tx) {
+        tx.executeSql('DELETE FROM persistence WHERE key = ? AND prefix = ?', [key, _validateAndSetPrefix(prefix)], function () {
+            return callback && callback();
+        });
+    });
+}
+
+function _removeAll(prefix, callback) {
+    utils.forEach(_cache, function (value, key) {
+        if (!prefix || key.indexOf(prefix) === 0) {
+            delete _cache[key];
+        }
+    });
+
+    _db.transaction(function (tx) {
+        if (prefix) {
+            tx.executeSql('DELETE FROM persistence WHERE prefix = ?', [prefix], function () {
+                return callback && callback();
+            });
+        } else {
+            tx.executeSql('DELETE FROM persistence', [], function () {
+                return callback && callback();
+            });
+        }
+    });
+}
+
+_self = {
+    save: function (key, value, prefix, callback) {
+        _save(key, value, prefix, callback);
+        event.trigger("StorageUpdatedEvent");
+    },
+
+    saveObject: function (key, obj, prefix, callback) {
+        _save(key, JSON.stringify(obj), prefix, callback);
+        event.trigger("StorageUpdatedEvent");
+    },
+
+    retrieve: function (key, prefix) {
+        return _retrieve(key, prefix);
+    },
+
+    retrieveObject: function (key, prefix) {
+        var retrievedValue = _retrieve(key, prefix);
+        return retrievedValue ? JSON.parse(retrievedValue) : retrievedValue;
+    },
+
+    retrieveAll: function (prefix, callback) {
+        return _retrieveAll(prefix, callback);
+    },
+
+    remove: function (key, prefix, callback) {
+        event.trigger("StorageUpdatedEvent");
+        _remove(key, prefix, callback);
+    },
+
+    removeAll: function (prefix, callback) {
+        _removeAll(prefix, callback);
+        event.trigger("StorageUpdatedEvent");
+    },
+
+    initialize: function (previous, baton) {
+        baton.take();
+
+        _db = openDatabase('tinyHippos', '1.0', 'tiny Hippos persistence', 1024 * 1024);
+        _db.transaction(function (tx) {
+            tx.executeSql('CREATE TABLE IF NOT EXISTS persistence (id unique, key, value, prefix)');
+
+            tx.executeSql('SELECT id, key, value, prefix FROM persistence', [], function (tx, results) {
+                var len = results.rows.length, i, item;
+
+                for (i = 0; i < len; i++) {
+                    item = results.rows.item(i);
+                    _cache[item.id] = item;
+                }
+
+                baton.pass();
+            });
+        });
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/notifications', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    exception = require('ripple/exception'),
+    utils = require('ripple/utils'),
+    event = require('ripple/event');
+
+function _validateAndInitNType(nType) {
+    nType = nType || "normal";
+
+    if (nType !== "normal" && nType !== "error") {
+        exception.raise(exception.types.NotificationType, "Unknown Notification Type == " + nType + ",when dealing with Console notification.");
+    }
+
+    return nType;
+}
+
+function _processNotification(nType, stateType, message) {
+    nType = _validateAndInitNType(nType);
+    message = message || "";
+
+    var display,
+        displayText,
+        className,
+        notificationIcon,
+        box = document.getElementById(constants.NOTIFICATIONS.MAIN_CONTAINER_CLASS),
+        msgBox = document.getElementById(constants.NOTIFICATIONS.MESSAGE_TEXT_CONTAINER_CLASS);
+
+    className = "ui-widget";
+
+    switch (stateType) {
+
+    case constants.NOTIFICATIONS.STATE_TYPES.CLOSE:
+        display = "display: none;"; //need to do this better.
+        displayText = "";
+        break;
+
+    case constants.NOTIFICATIONS.STATE_TYPES.OPEN:
+        display = "display: block;"; //need to do this better.
+        displayText = message;
+        if (nType === "error") {
+            displayText = "Oh Snap!\n\n" + displayText;
+            className += " ui-state-error ui-corner-all";
+            notificationIcon = '<span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span>';
+        }
+        else {
+            className += " ui-state-highlight ui-corner-all";
+            notificationIcon = '<span class="ui-icon ui-icon-info" style="float: left; margin-right: .3em;"></span>';
+        }
+        break;
+
+    default:
+        exception.raise(exception.types.NotificationStateType, "Unknown StateType == " + stateType.toString());
+    }
+
+    msgBox.innerHTML = notificationIcon + displayText;
+    box.setAttribute("class", className);
+    box.setAttribute("style", display);
+
+}
+
+module.exports = {
+    openNotification: function (nType, msg) {
+        _processNotification(nType, constants.NOTIFICATIONS.STATE_TYPES.OPEN, msg);
+    },
+
+    closeNotification: function (nType) {
+        _processNotification(nType, constants.NOTIFICATIONS.STATE_TYPES.CLOSE);
+    }
+};
+
+});
+require.define('ripple/xhr', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    utils = require('ripple/utils'),
+    ui = require('ripple/ui'),
+    helpers = require('ripple/xhr/helpers'),
+    XHR = window.XMLHttpRequest;
+
+module.exports = {
+    initialize: function (previous, baton) {
+        window.XMLHttpRequest = require('ripple/xhr/base');
+
+        if (helpers.proxyEnabled() && !ui.registered("omnibar")) {
+            var isFileScheme = utils.location().protocol.match(/^file:/);
+            window.XMLHttpRequest = require(isFileScheme ? 'ripple/xhr/jsonp' : 'ripple/xhr/cors');
+        }
+    }
+};
+
+});
+require.define('ripple/widgetConfig', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var exception = require('ripple/exception'),
+    event = require('ripple/event'),
+    app = require('ripple/app'),
+    _console = require('ripple/console'),
+    utils = require('ripple/utils'),
+    platform = require('ripple/platform'),
+    _validationResult = {
+        valid: false,
+        message: "",
+        value: null
+    },
+    _configValidationResults = null;
+
+function _failNodeValidation(schemaNode, message, value, node) {
+    var validationResult = utils.copy(_validationResult);
+
+    if (!schemaNode.validationResult) {
+        schemaNode.validationResult = [];
+    }
+    validationResult.valid = false;
+    if (value) {
+        validationResult.value = value;
+    }
+    else {
+        delete(validationResult.value);
+    }
+    validationResult.message = schemaNode.nodeName + message;
+    validationResult.node = node;
+
+    schemaNode.validationResult.push(validationResult);
+}
+
+function _createEmptyNodeValidation(node) {
+
+    var validationResult = utils.copy(_validationResult),
+        attributeValidationResult, attribute;
+
+    if (!node.validationResult) {
+        node.validationResult = [];
+    }
+
+    validationResult.value = "";
+    delete(validationResult.valid);
+    delete(validationResult.message);
+
+    if (node.attributes) {
+        for (attribute in node.attributes) {
+            if (node.attributes.hasOwnProperty(attribute)) {
+                if (!validationResult.attributes) {
+                    validationResult.attributes = {};
+                }
+
+                attributeValidationResult = utils.copy(_validationResult);
+
+                attributeValidationResult.attributeName = node.attributes[attribute].attributeName;
+                delete(attributeValidationResult.value);
+                delete(attributeValidationResult.valid);
+                delete(attributeValidationResult.message);
+
+                validationResult.attributes[attributeValidationResult.attributeName] = attributeValidationResult;
+            }
+        }
+    }
+
+    node.validationResult.push(validationResult);
+}
+
+function _validateValue(valueToTest, schemaNode) {
+    var failMessage = "",
+        nodeValue,
+        numbers,
+        numberRangeIndex,
+        numberRange,
+        range1,
+        range2;
+
+    switch (schemaNode.type) {
+    case "string":
+        if (typeof valueToTest !== "string") {
+            failMessage = " value was expected to be of type string but was typeof: " + typeof(valueToTest);
+        }
+        break;
+    case "number":
+        nodeValue = parseFloat(valueToTest);
+        if (isNaN(nodeValue)) {
+            failMessage = " value was expected to be of type number but was typeof: " + typeof(valueToTest);
+        }
+        break;
+    case "integer":
+        nodeValue = parseInt(valueToTest, 10);
+        if (isNaN(nodeValue)) {
+            failMessage = " value was expected to be of type number but was typeof: " + typeof(valueToTest);
+        }
+        break;
+    case "boolean":
+        if (valueToTest !== "false" && valueToTest !== "true") {
+            failMessage = " value was expected to be of type boolean (i.e. 'true' or 'false' but was: " + valueToTest;
+        }
+        break;
+    case "list":
+        if (!utils.arrayContains(schemaNode.listValues, valueToTest)) {
+            failMessage = " value is not recognized as being valid, it was:<br/><br/><span class=\"ui-text-fail\">" + valueToTest +
+                    "</span><br/><br/>Valid values are:<p class=\"ui-text-pass\">" + schemaNode.listValues.join(" <br/> ") + "</p>";
+        }
+        break;
+    case "listBoolean":
+    case "listDefault":
+        if (!utils.arrayContains(schemaNode.listValues, valueToTest)) {
+            failMessage = " value is not recognized as being valid, it was:<br/><br/><span class=\"ui-text-fail\">" + valueToTest +
+                    "</span><br/><br/>The framework will assume the value to be:<p class=\"ui-text-pass\">" + schemaNode.defaultValue + "</p>";
+        }
+        break;
+    case "listNumbers":
+        numbers = valueToTest.split(",");
+
+        for (numberRangeIndex = 0; numberRangeIndex < numbers.length; numberRangeIndex++) {
+            numberRange = valueToTest.split("-");
+            if (numberRange.length > 1) {
+                range1 = parseInt(numberRange[0], 10);
+                range2 = parseInt(numberRange[1], 10);
+                if (isNaN(range1) || isNaN(range2)) {
+                    failMessage = " range values where not recognized as being valid, they was: " + range1 +
+                            " and " + range2 + " :: valid values should be of type 'integer'";
+                    break;
+                }
+            }
+            else if (numberRange.length === 1) {
+                range1 = parseInt(numberRange[0], 10);
+                if (isNaN(range1)) {
+                    failMessage = " value was not recognized as being valid, it was: " + range1 +
+                            " :: valid values should be of type 'integer'";
+                    break;
+                }
+            }
+        }
+        break;
+    case "regex":
+        if (!valueToTest.match(schemaNode.regex)) {
+            failMessage = " value does not match expected format. Value should pass this regular expression validation: " + schemaNode.regex;
+        }
+        break;
+    case "iso-language":
+        break;
+    default:
+        exception.raise(exception.types.Application, "Schema node with value type of: " + schemaNode.type + " is not known");
+    }
+
+    return failMessage;
+}
+
+function _passNodeValidation(schemaNode, value, node) {
+    var validationResult = utils.copy(_validationResult);
+
+    if (!schemaNode.validationResult) {
+        schemaNode.validationResult = [];
+    }
+    validationResult.valid = true;
+    validationResult.node = node;
+    if (value) {
+        validationResult.value = value;
+    }
+    else {
+        delete(validationResult.value);
+    }
+    delete(validationResult.message);
+
+    schemaNode.validationResult.push(validationResult);
+}
+
+function _validateNodeValue(schemaNode, node) {
+    var failMessage,
+        valueToTest = node && node.nodeValue ? node.nodeValue.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : null;
+
+    if (schemaNode.type && valueToTest) {
+
+        failMessage = _validateValue(valueToTest, schemaNode);
+
+        if (failMessage !== "") {
+            _failNodeValidation(schemaNode, failMessage, valueToTest, node);
+            return;
+        }
+    }
+    _passNodeValidation(schemaNode, valueToTest, node);
+}
+
+function _failNodeAttributeValidation(node, attribute, message, value) {
+    var nodeValidationResult = node.validationResult ? node.validationResult.pop() : utils.copy(_validationResult),
+        attributeValidationResult = utils.copy(_validationResult);
+
+    if (!nodeValidationResult.attributes) {
+        nodeValidationResult.attributes = {};
+    }
+
+    nodeValidationResult.valid = false;
+    nodeValidationResult.message = "One or more attributes failed validation";
+
+    attributeValidationResult.attributeName = attribute.attributeName;
+    attributeValidationResult.valid = false;
+    if (value) {
+        attributeValidationResult.value = value;
+    }
+    else {
+        delete(attributeValidationResult.value);
+    }
+    attributeValidationResult.message = node.nodeName + "." + attribute.attributeName + message;
+
+    nodeValidationResult.attributes[attribute.attributeName] = attributeValidationResult;
+    node.validationResult.push(nodeValidationResult);
+}
+
+function _passNodeAttributeValidation(node, attribute, value) {
+    var nodeValidationResult = node.validationResult ? node.validationResult.pop() : utils.copy(_validationResult),
+        attributeValidationResult = utils.copy(_validationResult);
+
+    if (!nodeValidationResult.attributes) {
+        nodeValidationResult.attributes = {};
+    }
+
+    attributeValidationResult.attributeName = attribute.attributeName;
+    attributeValidationResult.valid = true;
+    if (value) {
+        attributeValidationResult.value = value;
+    }
+    else {
+        delete(attributeValidationResult.value);
+    }
+    delete(attributeValidationResult.message);
+
+    nodeValidationResult.attributes[attribute.attributeName] = attributeValidationResult;
+    node.validationResult.push(nodeValidationResult);
+}
+
+function _validateNodeAttributeValue(schemaNode, schemaNodeAttribute, attribute) {
+    var failMessage,
+        valueToTest = attribute ? attribute.value.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : null;
+
+    if (schemaNodeAttribute.type && valueToTest) {
+
+        failMessage = _validateValue(valueToTest, schemaNodeAttribute);
+
+        if (failMessage !== "") {
+            _failNodeAttributeValidation(schemaNode, schemaNodeAttribute, failMessage, valueToTest);
+            return;
+        }
+    }
+    _passNodeAttributeValidation(schemaNode, schemaNodeAttribute, valueToTest);
+}
+
+function _validateNodeAttributes(schemaNode, node, children) {
+
+    var siblings = utils.filter(children, function (child) {
+            return child !== node;
+        }),
+        attributeConverter = function (attribute) {
+            var _self = {
+                toValue: function (n) {
+                    var obj = _self.toNode(n);
+                    return obj ? obj.value : null;
+                },
+                toNode: function (n) {
+                    return n.attributes.getNamedItem(attribute.attributeName);
+                }
+            };
+
+            return _self;
+        };
+
+    utils.forEach(schemaNode.attributes, function (attribute) {
+
+        var convert = attributeConverter(attribute),
+            dupe = false;
+
+        if (attribute.unique) {
+            // this means we need to check and see if there are other node with the same name
+            // and ensure that they have a different value for this attributes, if not... fail
+
+            dupe = siblings.some(function (sibling) {
+                return convert.toValue(sibling) === convert.toValue(node);
+            });
+
+            if (dupe) {
+                _failNodeAttributeValidation(schemaNode,
+                        attribute,
+                        " node is allowed to appear multiple times, however it must be unique based on this attribute and in this case another node with an identical attribute vale was found",
+                        convert.toValue(node));
+                return;
+            }
+        }
+
+        if (attribute.required && !convert.toValue(node)) {
+            _failNodeAttributeValidation(schemaNode, attribute, " attribute was expected but not found", null);
+        }
+        else {
+            _validateNodeAttributeValue(schemaNode, attribute, convert.toNode(node));
+        }
+    });
+}
+
+
+function _validateNode(schemaNode, parentNode) {
+    var children = utils.filter(parentNode.childNodes, function (child) {
+        return child && child.nodeName === schemaNode.nodeName;
+    });
+
+    if (children.length === 0) {
+        if (schemaNode.required) {
+            _failNodeValidation(schemaNode, " node expected, but not found", null, null);
+        }
+    }
+
+    utils.forEach(children, function (child) {
+        if (schemaNode.occurrence !== 0 && schemaNode.occurrence < children.length) {
+            _failNodeValidation(schemaNode, " node: more then " + schemaNode.occurrence + " node(s) found", null, child);
+        }
+        else {
+            _validateNodeValue(schemaNode, child.childNodes[0] || child);
+
+            _validateNodeAttributes(schemaNode, child, children);
+        }
+
+        utils.forEach(schemaNode.children, function (schema) {
+            _validateNode(schema, child);
+        });
+    });
+}
+
+function _validateAgainstSchemaNode(configSchema, configXML) {
+    var results = utils.copy(configSchema);
+    try {
+        _validateNode(results[configSchema.rootElement], configXML);
+    }
+    catch (e) {
+        exception.handle(e, true);
+    }
+
+    return results;
+}
+
+function _validate(configXML) {
+    // traverse the config schema JSON object
+    // TODO: update to get platform.getPlatformConfigSpec().schema
+    return _validateAgainstSchemaNode(platform.current().config.schema, configXML);
+}
+
+function _process(results) {
+    // Check to make sure that widget is the correct version (i.e. config.xml needs to match selected platform)
+    var validVersion = app.validateVersion(results);
+
+    if (!validVersion) {
+        _console.warn("Your application does not appear to match" +
+                " the platform you have selected. The version number in your configuration might not " +
+                "match the selected platform version or your configuration file has errors in it.");
+    }
+
+    // save widget info
+    app.saveInfo(results);
+    event.trigger("WidgetInformationUpdated");
+
+    // Check for readonly preferences (WAC only?)
+
+    if (app.getInfo().preferences !== {}) {
+        event.trigger("StorageUpdatedEvent");
+    }
+}
+
+module.exports = {
+
+    validate: function (configXML) {
+        utils.validateNumberOfArguments(1, 1, arguments.length);
+        return _validate(configXML);
+    },
+
+    initialize: function (previous, baton) {
+        var xmlHttp = new XMLHttpRequest(),
+            config = platform.current().config,
+            fileName = config ? config.fileName : null,
+            results;
+
+        if (!fileName) {
+            return;
+        }
+
+        try {
+            xmlHttp.open("GET", utils.appLocation() + fileName, false);
+            xmlHttp.send();
+            if (xmlHttp.responseXML) {
+                results = _validate(xmlHttp.responseXML);
+                _process(results);
+                _configValidationResults = results;
+            }
+            else {
+                _process();
+                _configValidationResults = null;
+                require('ripple/ui/plugins/widgetConfig').initialize();
+            }
+        }
+        catch (e) {
+            exception.handle(e);
+        }
+    },
+
+    getValidationResults: function () {
+        return _configValidationResults;
+    }
+};
+
+});
+require.define('ripple/app', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _data = {},
+    utils = require('ripple/utils'),
+    _self;
+
+_self = {
+    setInfo: function (info) {
+        if (!info) {
+            _data = {};
+        }
+        _data = info;
+    },
+
+    getInfo: function () {
+        return utils.copy(_data);
+    },
+
+    isPreferenceReadOnly: function (key) {
+        return (_data.preferences &&
+                _data.preferences[key] &&
+                _data.preferences[key].readonly &&
+                _data.preferences[key].readonly === true);
+    },
+
+    validateVersion: function (configValidationObject) {
+        // TODO: WTF figure this out, platform is empty object when require at require time
+        // could be that the new platform _getBuilder code dies when called, beforre it is initialized
+        var spec = require('ripple/platform').current();
+        if (typeof spec.config.validateVersion === "function" && configValidationObject) {
+            return spec.config.validateVersion(configValidationObject);
+        }
+
+        return true;
+    },
+
+    saveInfo: function (configValidationObject) {
+        var spec = require('ripple/platform').current(),
+            info = null;
+        if (typeof spec.config.extractInfo === "function") {
+            info = spec.config.extractInfo(configValidationObject);
+        }
+
+        if (info) {
+            _self.setInfo(info);
+        }
+    }
+
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/documentEventListener', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var event = require('ripple/event'),
+    constants = require('ripple/constants'),
+    deviceSettings = require('ripple/deviceSettings'),
+    ui = require('ripple/ui'),
+    _self;
+
+function _bind(name, win) {
+    var _listeners = [];
+
+    return {
+        add: function (callback, useCapture) {
+            // ignore non-function
+            if (typeof callback === "function") {
+                // ignore useCapture as we could not handle it
+                if (!useCapture) {
+                    if (!_listeners.some(function (listener) {
+                        return (listener === callback);
+                    })) {
+                        _listeners.push(callback);
+                    }
+                }
+            }
+        },
+        exec: function (arg) {
+            _listeners.forEach(function (listener) {
+                listener.apply(win, arg);
+            });
+        },
+        remove: function (callback, useCapture) {
+            // ignore non-function
+            if (typeof callback === "function") {
+                // ignore useCapture as we do not add them into _listeners
+                if (!useCapture) {
+                    _listeners = _listeners.filter(function (listener) {
+                        return (listener !== callback);
+                    });
+                }
+            }
+        }
+    };
+}
+
+_self = {
+    mask: function (frame) {
+        /* 
+         * The current issue is that "document.addEventListener(visibilitychange, function(){...})" 
+         * does not work if it is invoked in the document.DOMContentLoaded listeners, for example, at 
+         * JQuery(document).ready function.
+
+         * The reason is that window.DOMContentLoaded is fired after the document.DOMContentLoaded. 
+         * Currently we have not found a proper event to override the document.addEventListener. 
+         * The beforeload is fine for window.addEventListener, while does not work for document.addEventListener 
+         * because the contentDocument will be reset after loading. 
+         */
+        frame.contentWindow.addEventListener("DOMContentLoaded", function () {
+            var widgetDocument = frame.contentDocument,
+                _pageVisibility,
+                add = widgetDocument.addEventListener,
+                remove = widgetDocument.removeEventListener;
+
+            widgetDocument.PAGE_HIDDEN  = "hidden";
+            widgetDocument.PAGE_VISIBLE = "visible";
+            widgetDocument.PAGE_PREVIEW = "preview";
+
+            function _lockScreen(on) {
+                var hidden = on;
+
+                if (on) {
+                    ui.showOverlay("lock-screen-window", function (background) {});
+                } else {
+                    ui.hideOverlay("lock-screen-window", function (background) {});
+                }
+
+                event.trigger("visibilitychange", [hidden]);
+            }
+
+            function _isLockScreenOn() {
+                return deviceSettings.retrieve("Config.lockScreen");
+            }
+
+            _lockScreen(_isLockScreenOn());
+
+            _pageVisibility = _bind("visibilitychange", frame.contentWindow);
+
+            widgetDocument.addEventListener = function (event, callback, useCapture) {
+                switch (event) {
+                case "visibilitychange":
+                    _pageVisibility.add(callback, useCapture);
+                    break;
+
+                default:
+                    add.apply(widgetDocument, arguments);
+                    break;
+                }
+            };
+
+            widgetDocument.removeEventListener = function (event, callback, useCapture) {
+                _pageVisibility.remove(callback, useCapture);
+                remove.apply(widgetDocument, arguments);
+            };
+
+            event.on("LockScreenChanged", function (on) {
+                _lockScreen(on);
+            });
+
+            event.on("visibilitychange", function (hidden) {
+                widgetDocument.hidden = hidden;
+                widgetDocument.visibilityState = hidden ? widgetDocument.PAGE_HIDDEN : widgetDocument.PAGE_VISIBLE;
+                _pageVisibility.exec();
+            });
+        });
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/event', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    _listeners = {};
+
+function _on(eventType, listener, scope, once) {
+    if (!eventType) {
+        throw "eventType must be truthy";
+    }
+    _listeners[eventType] = _listeners[eventType] || [];
+    _listeners[eventType].push({
+        func: listener,
+        scope: scope,
+        once: !!once
+    });
+}
+
+function _deleteEventHandler(eventType, listener, scope) {
+    if (!eventType) {
+        throw "eventType must be truthy";
+    }
+
+    var listeners = _listeners[eventType];
+
+    if (listeners && listeners.length === 1) {
+        delete _listeners[eventType];
+    }
+    else {
+        _listeners[eventType] = listeners.filter(function (listener) {
+            return (listener.func !== listener);
+        });
+    }
+}
+
+function _trigger(listener, args, sync) {
+    try {
+        if (sync) {
+            listener.func.apply(listener.scope, args);
+        }
+        else {
+            setTimeout(function () {
+                listener.func.apply(listener.scope, args);
+            }, 1);
+        }
+    }
+    catch (e) {
+        exception.handle(e);
+    }
+}
+
+module.exports = {
+    on: function (eventType, listener, scope) {
+        _on(eventType, listener, scope, false);
+    },
+
+    once: function (eventType, listener, scope) {
+        _on(eventType, listener, scope, true);
+    },
+
+    trigger: function (eventType, args, sync) {
+        args = args || [];
+        sync = sync || false;
+
+        var listeners = _listeners[eventType];
+
+        if (listeners) {
+            listeners.forEach(function (listener) {
+                _trigger(listener, args, sync);
+            });
+
+            _listeners[eventType] = listeners.filter(function (listener) {
+                return !listener.once;
+            });
+        }
+    },
+
+    eventHasSubscriber: function (eventType) {
+        return !!_listeners[eventType];
+    },
+
+    getEventSubscribers: function (eventType) {
+        return utils.copy(_listeners[eventType]) || [];
+    },
+
+    clear: function (eventType) {
+        if (eventType) {
+            delete _listeners[eventType];
+        }
+    },
+
+    deleteEventHandler: function (eventType, listener, scope) {
+        if (eventType) {
+            _deleteEventHandler(eventType, listener, scope, false);
+        }
+    }
+};
+
+});
+require.define('ripple/sensorSettings', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _PERSISTENCE_KEY = "sensorsettings",
+    db = require('ripple/db'),
+    platform = require('ripple/platform'),
+    _currentSensorSettings = {},
+    _self;
+
+function _default(key) {
+    var keys = key.split("."),
+        defaults = platform.current().sensor;
+
+    if (keys.length === 1)
+        return defaults[key];
+
+    return keys.length === 2 &&
+           defaults[keys[0]] &&
+           defaults[keys[0]][keys[1]] &&
+           defaults[keys[0]][keys[1]].control ?
+           defaults[keys[0]][keys[1]].control.value : undefined;
+}
+
+_self = {
+    initialize: function () {
+        _currentSensorSettings = db.retrieveObject(_PERSISTENCE_KEY) || {};
+    },
+    register: function (key, obj) {
+        _currentSensorSettings[key] = obj;
+    },
+
+    persist: function (key, obj) {
+        if (key) {
+            _currentSensorSettings[key] = obj;
+        }
+
+        db.saveObject(_PERSISTENCE_KEY, _currentSensorSettings);
+    },
+
+    retrieve: function (key) {
+        return _currentSensorSettings.hasOwnProperty(key) ?
+               _currentSensorSettings[key] : _default(key);
+    },
+
+    retrieveAsInt: function (key) {
+        return parseInt(_self.retrieve(key), 10);
+    },
+
+    retrieveAsBoolean: function (key) {
+        return !!_self.retrieve(key);
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/fs', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    _console = require('ripple/console'),
+    _self, _fs;
+
+function _map(array, callback) {
+    var map = [], i;
+    for (i = 0; i < array.length; i++) {
+        map[i] = callback(array[i], i);
+    }
+    return map;
+}
+
+function _resolveLocalFileSystemURL(path, success, error) {
+    return (window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL)(path, success, error);
+}
+
+function _blobBuilder() {
+    var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
+    return new BlobBuilder();
+}
+
+function _error(e) {
+    var msg = '';
+
+    switch (e.code) {
+    case FileError.QUOTA_EXCEEDED_ERR:
+        msg = 'QUOTA_EXCEEDED_ERR';
+        break;
+    case FileError.NOT_FOUND_ERR:
+        msg = 'NOT_FOUND_ERR';
+        break;
+    case FileError.SECURITY_ERR:
+        msg = 'SECURITY_ERR';
+        break;
+    case FileError.INVALID_MODIFICATION_ERR:
+        msg = 'INVALID_MODIFICATION_ERR';
+        break;
+    case FileError.INVALID_STATE_ERR:
+        msg = 'INVALID_STATE_ERR';
+        break;
+    default:
+        msg = 'Unknown Error';
+        break;
+    }
+
+    _console.log('FileSystem error: ' + msg);
+}
+
+_self = {
+    initialize: function (prev, baton) {
+        try {
+            var requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
+
+            if (requestFileSystem) {
+                baton.take();
+            }
+
+            requestFileSystem(window.TEMPORARY, constants.FS_SIZE, function (fs) {
+                _fs = fs;
+                event.trigger("FileSystemInitialized", null, true);
+                baton.pass();
+            }, _error);
+        }
+        catch (e) {
+            console.log("File System Not Available");
+        }
+    },
+
+    ls: function (path, success, error) {
+        path = path || "/";
+
+        _fs.root.getDirectory(path, {}, function (dirEntry) {
+            var dirReader = dirEntry.createReader();
+            dirReader.readEntries(function (entries) {
+                success(_map(entries, function (entry, index) {
+                    return entry;
+                }));
+            }, error);
+        }, error);
+    },
+
+    rm: function (path, success, error, options) {
+        options = options || {};
+
+        _fs.root[options.recursive ? "getDirectory" : "getFile"](path, {create: false}, function (entry) {
+            entry[options.recursive ? "removeRecursively" : "remove"](function () {
+                success();
+            }, error);
+        }, error);
+    },
+
+    rmdir: function (path, success, error, options) {
+        options = options || {};
+
+        _fs.root.getDirectory(path, {create: false}, function (entry) {
+            entry.remove(function () {
+                success();
+            }, error);
+        }, error);
+    },
+
+    mkdir: function (path, success, error) {
+        _fs.root.getDirectory(path, {create: true}, function (dirEntry) {
+            success(dirEntry);
+        }, error);
+    },
+
+    mv: function (from, to, success, error) {
+        var path = to.replace(/^\//, "").split("/"),
+            fileName = path.splice(path.length - 1, 1).toString();
+
+        _self.stat(from, function (entry) {
+            _self.stat(path.length > 0 ? path.join("/") : "/", function (dest) {
+                entry.moveTo(dest, fileName, function (finalDestination) {
+                    success(finalDestination);
+                }, error);
+            }, error);
+        }, error);
+    },
+
+    touch: function (path, success, error) {
+        _fs.root.getFile(path, {create: true}, function (fileEntry) {
+            success(fileEntry);
+        }, error);
+    },
+
+    cp: function (from, to, success, error) {
+        var path = to.replace(/^\//, "").split("/"),
+            fileName = path.splice(path.length - 1, 1).toString();
+
+        _self.stat(from, function (entry) {
+            _self.stat(path.length > 0 ? path.join("/") : "/", function (dest) {
+                entry.copyTo(dest, fileName, function (finalDestination) {
+                    success(finalDestination);
+                }, error);
+            }, error);
+        }, error);
+    },
+
+    stat: function (path, success, error) {
+        var url = "filesystem:" + utils.location().origin + "/temporary/" + path;
+        _resolveLocalFileSystemURL(url, function (entry) {
+            success(entry);
+        }, error);
+    },
+
+    write: function (path, contents, success, error, options) {
+        options = options || {};
+
+        function write(entry) {
+            entry.createWriter(function (fileWriter) {
+                var bb = _blobBuilder();
+
+                fileWriter.onwriteend = function (progressEvent) {
+                    success(entry);
+                };
+                fileWriter.onerror = error;
+
+                if (options.mode === "append") {
+                    fileWriter.seek(fileWriter.length);
+                }
+
+                bb.append(contents);
+                fileWriter.write(bb.getBlob('text/plain'));
+            }, error);
+        }
+
+        _self.stat(path, function (entry) {
+            if (options.mode === "append") {
+                write(entry);
+            } else {
+                _self.rm(path, function () {
+                    _self.touch(path, write, error);
+                }, error);
+            }
+        }, function (e) {
+            if (e.code === FileError.NOT_FOUND_ERR) {
+                _self.touch(path, write, error);
+            } else {
+                error(e);
+            }
+        });
+    },
+
+    read: function (path, success, error) {
+        _self.stat(path, function (entry) {
+            entry.file(function (file) {
+                var reader = new FileReader();
+
+                reader.onloadend = function (progressEvent) {
+                    success(progressEvent.target.result);
+                };
+                reader.onerror = error;
+
+                reader.readAsText(file);
+            }, error);
+        }, error);
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/touchEventEmulator', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var emulatorBridge = require('ripple/emulatorBridge'),
+    utils = require('ripple/utils'),
+    _isMouseDown, self;
+
+// NOTE: missing view, detail, touches, targetTouches, scale and rotation
+function _initTouchEvent(type, canBubble, cancelable, eventData) {
+    var touchEvent = emulatorBridge.document().createEvent("Event");
+    touchEvent.initEvent(type, canBubble, cancelable);
+    utils.mixin(eventData, touchEvent);
+    return touchEvent;
+}
+
+function _raiseTouchEvent(mouseEvent) {
+    var type = "",
+        preventDefault = false,
+        simulatedEvent,
+        touchObj,
+        eventData;
+
+    switch (mouseEvent.type) {
+    case "mousedown":
+        type = "touchstart";
+        _isMouseDown = true;
+        break;
+    case "mousemove":
+        if (!_isMouseDown) {
+            return;
+        }
+        type = "touchmove";
+        preventDefault = true;
+        break;
+    case "mouseup":
+        type = "touchend";
+        _isMouseDown = false;
+        break;
+    default:
+        return;
+    }
+
+    touchObj = {
+        clientX: mouseEvent.clientX,
+        clientY: mouseEvent.clientY,
+        identifier: "",
+        pageX: mouseEvent.pageX,
+        pageY: mouseEvent.pageY,
+        screenX: mouseEvent.screenX,
+        screenY: mouseEvent.screenY,
+        target: mouseEvent.target
+    };
+
+    eventData = {
+        altKey: mouseEvent.altKey,
+        ctrlKey: mouseEvent.ctrlKey,
+        shiftKey: mouseEvent.shiftKey,
+        metaKey: mouseEvent.metaKey,
+        changedTouches: [touchObj],
+        targetTouches: [touchObj],
+        touches: [touchObj]
+    };
+
+    utils.mixin(touchObj, eventData);
+
+    simulatedEvent = _initTouchEvent(type, true, true, eventData);
+
+    mouseEvent.target.dispatchEvent(simulatedEvent);
+
+    if (typeof mouseEvent.target["on" + type] === "function") {
+        mouseEvent.target["on" + type].apply(mouseEvent.target, [simulatedEvent]);
+    }
+
+    if (preventDefault) {
+        mouseEvent.preventDefault();
+    }
+}
+
+function _marshalEvents(doc) {
+    utils.forEach(["mousedown", "mousemove", "mouseup"],
+        function (event) {
+            doc.addEventListener(event, _raiseTouchEvent, true);
+        });
+}
+
+self = module.exports = {
+    mask: function (frame) {
+        frame.contentWindow.addEventListener("DOMContentLoaded", function () {
+            _marshalEvents(frame.contentDocument);
+        });
+    }
+};
+
+});
+require.define('ripple/emulatorBridge', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _isMouseDown = false,
+    platform = require('ripple/platform'),
+    builder = require('ripple/platform/builder'),
+    constants = require('ripple/constants'),
+    utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    _xhr,
+    _frame;
+
+function _getEmulatedViewportStyle(attr) {
+    var vp = document.getElementById(constants.COMMON.VIEWPORT_CONTAINER);
+    return vp["client" + attr];
+}
+
+function _screenAvailWidth() {
+    return _getEmulatedViewportStyle("Width");
+}
+
+function _screenAvailHeight() {
+    return _getEmulatedViewportStyle("Height");
+}
+
+function _screenWidth() {
+    return _getEmulatedViewportStyle("Width");
+}
+
+function _screenHeight() {
+    return _getEmulatedViewportStyle("Height");
+}
+
+function _window_innerWidth() {
+    return _getEmulatedViewportStyle("Width");
+}
+
+function _window_innerHeight() {
+    return _getEmulatedViewportStyle("Height");
+}
+
+function _marshalScreen(win) {
+    utils.forEach({
+        "availWidth": _screenAvailWidth,
+        "availHeight": _screenAvailHeight,
+        "width": _screenWidth,
+        "height": _screenHeight
+    }, function (mappedFunc, prop) {
+        win.screen.__defineGetter__(prop, mappedFunc);
+    });
+
+    utils.forEach({
+        "innerWidth": _window_innerWidth,
+        "innerHeight": _window_innerHeight
+    }, function (mappedFunc, prop) {
+        win.__defineGetter__(prop, mappedFunc);
+    });
+}
+
+module.exports = {
+    link: function  (frame) {
+        _frame = frame;
+        _xhr = frame.contentWindow.XMLHttpRequest;
+
+        require('ripple/widgetConfig').initialize();
+
+        var marshal = function (obj, key) {
+                window[key] = _frame.contentWindow[key] = obj;
+            },
+            sandbox = {};
+
+        marshal(window.tinyHippos, "tinyHippos");
+        marshal(window.XMLHttpRequest, "XMLHttpRequest");
+        window.onmessage = function (e) {
+            if (typeof _frame.contentWindow.onmessage === 'function') {
+                _frame.contentWindow.onmessage(e);
+            }
+        };
+
+        builder.build(platform.current().objects).into(sandbox);
+
+        utils.forEach(sandbox, marshal);
+
+        _marshalScreen(_frame.contentWindow);
+        _marshalScreen(window);
+    },
+
+    document: function () {
+        return _frame.contentDocument;
+    },
+
+    window: function () {
+        return _frame.contentWindow;
+    },
+
+    xhr: function () {
+        return _xhr;
+    }
+};
+
+});
+require.define('ripple/exception', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _console = require('ripple/console');
+
+function _getStack(depth) {
+    var caller,
+        stack = "",
+        count = 0;
+
+    try {
+        caller = arguments.callee.caller.arguments.callee.caller;
+
+        while (count <= depth && caller) {
+            stack += "function: " + caller.toString().match(/function\s?(.*)\{/)[1] + "\n";
+            caller = caller.arguments.callee.caller;
+            count++;
+        }
+    } catch (e) {
+        stack = "failed to determine stack trace (" + (e.name || e.type) + " :: " + e.message + ")";
+    }
+
+    return stack;
+}
+
+module.exports = {
+
+    types: {
+        Application: "Application",
+        ArgumentLength: "ArgumentLength",
+        ArgumentType: "ArgumentType",
+        Argument: "Argument",
+        NotificationType: "NotificationType",
+        NotificationStateType: "NotificationStateType",
+        DomObjectNotFound: "DomObjectNotFound",
+        LayoutType: "LayoutType",
+        DeviceNotFound: "DeviceNotFound",
+        tinyHipposMaskedException: "tinyHipposMaskedException",
+        Geo: "Geo",
+        Accelerometer: "Accelerometer",
+        MethodNotImplemented: "MethodNotImplemented",
+        InvalidState: "InvalidState",
+        ApplicationState: "ApplicationState"
+    },
+
+    handle: function handle(exception, reThrow) {
+        reThrow = reThrow || false;
+
+        var eMsg = exception.message || "exception caught!",
+        msg = eMsg + "\n\n" + (exception.stack || "*no stack provided*") + "\n\n";
+
+        _console.error(msg);
+
+        if (reThrow) {
+            throw exception;
+        }
+    },
+
+    raise: function raise(exceptionType, message, customExceptionObject) {
+        var obj = customExceptionObject || {
+                type: "",
+                message: "",
+
+                toString: function () {
+                    var result = this.name + ': "' + this.message + '"';
+
+                    if (this.stack) {
+                        result += "\n" + this.stack;
+                    }
+                    return result;
+                }
+            };
+
+        message = message || "";
+
+        obj.name = exceptionType;
+        obj.type = exceptionType;
+        // TODO: include the exception objects original message if exists
+        obj.message = message;
+        obj.stack = _getStack(5);
+
+        throw obj;
+    },
+
+    throwMaskedException: function throwMaskedException(exceptionType, message, customExceptionObject) {
+        try {
+            this.raise.apply(this, arguments);
+        } catch (e) {
+            this.handle(e);
+        }
+        this.raise(this.types.tinyHipposMaskedException, "tinyhippos terminated your script due to exception");
+    }
+
+};
+
+});
+require.define('ripple/bootstrap', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _bound,
+    _console = require('ripple/console'),
+    db = require('ripple/db'),
+    _CURRENT_URL = "current-url";
+
+function _bindObjects(frame) {
+    if (!frame.contentWindow.tinyHippos) {
+        require('ripple/emulatorBridge').link(frame);
+        require('ripple/platform/tizen/1.0/touchEvent').mask(frame);
+        require('ripple/touchEventEmulator').mask(frame);
+        require('ripple/deviceMotionEmulator').init(frame);
+        require('ripple/documentEventListener').mask(frame);
+        _bound = true;
+    }
+}
+
+function _createFrame(src) {
+    var frame = document.createElement("iframe");
+    frame.setAttribute("id", "document");
+    frame.src = src;
+
+    frame.addEventListener("beforeload", function () {
+        _bound = false;
+        _bindObjects(frame);
+        var id = window.setInterval(function () {
+                if (_bound) {
+                    window.clearInterval(id);
+                } else {
+                    _bindObjects(frame);
+                }
+            }, 1);
+    });
+
+    return frame;
+}
+
+function _cleanBody() {
+    require('ripple/utils').forEach(document.body.children, function (child) {
+        if (child && child.id && !child.id.match(/ui|tooltip/)) {
+            document.body.removeChild(child);
+        }
+
+        document.body.removeAttribute("style");
+        document.body.removeAttribute("id");
+        document.body.removeAttribute("class");
+    });
+}
+
+function _post(src) {
+    var event = require('ripple/event'),
+        frame = _createFrame(src);
+
+    _console.log("Initialization Finished (Make it so.)");
+
+    frame.onload = function () {
+        var bootLoader = document.querySelector("#emulator-booting"),
+            id;
+        if (bootLoader) {
+            document.querySelector("#ui").removeChild(bootLoader);
+        }
+
+        event.trigger("TinyHipposLoaded");
+
+        _cleanBody();
+        id = window.setInterval(_cleanBody, 20);
+
+        window.setTimeout(function () {
+            window.clearInterval(id);
+        }, 1200);
+
+        //reset the onload function so that when navigating we can destroy
+        //the iframe and create a new one so we can reinject the platform by
+        //calling post again.
+        frame.onload = function () {
+            var url = frame.contentWindow.location.href;
+            document.getElementById("viewport-container").removeChild(frame);
+            if (url !== undefined)
+                event.trigger("FrameHistoryChange", [url]);
+            _console.log("-----------------------------------------------------------");
+            _console.log("Pay no attention to that man behind the curtain.");
+            _console.log("Environment Warning up again (Set main batteries to auto-fire cycle)");
+            _post(url);
+        };
+    };
+
+    // append frame
+    document.getElementById("viewport-container").appendChild(frame);
+
+    delete tinyHippos.boot;
+}
+
+function _bootstrap() {
+    // TODO: figure this out for web and ext
+    //_console.log("-----------------------------------------------------------");
+    //_console.log("There be dragons above here!");
+    _console.log("Ripple :: Environment Warming Up (Tea. Earl Gray. Hot.)");
+
+    window.tinyHippos = require('ripple');
+
+    tinyHippos.boot(function () {
+        var ui = require('ripple/ui'),
+            //HACK: this seems wrong and makes babies cry
+            uri = ui.registered('omnibar') ?
+                require('ripple/ui/plugins/omnibar').currentURL() :
+                document.documentURI.replace(/enableripple=true[&]/i, "").replace(/[\?&]$/, "");
+
+        _post(uri);
+        delete tinyHippos.boot;
+    });
+}
+
+module.exports = {
+    bootstrap: _bootstrap
+};
+
+});
+require.define('ripple/constants', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = {
+    "API_URL": "http://api.tinyhippos.com",
+
+    "SERVICES": {
+        "GOOGLE_MAPS_URI": "http://maps.google.com/maps/api/staticmap?size=476x476&maptype=roadmap",
+        "GOOGLE_MAPS_API_KEY": "ABQIAAAA-CaPZHXR-0Tzhui_h6gpjhSE_2rGlnYiB7L-ZGVwgaut5s7OYRSlBAaHCzBuZf2_23_vrCOfPxXHjA"
+    },
+
+    "FS_SIZE": 1024 * 1024 * 10,
+
+    "COMMON":  {
+        "APPLICATION_STATE": "ui-application-state-",
+        "PREFIX": "tinyhippos-",
+        "DEVICE_CONTAINER" : "device-container",
+        "VIEWPORT_CONTAINER" : "viewport-container",
+        "MENU_BUTTON" : "menu-button",
+        "BACK_BUTTON" : "back-button",
+        "HTML_CONTAINER" : "document",
+        "INFO_SECTION": "information-sub-container",
+        "ORIENTATION_SELECT_PORTRAIT_ID" : "layout-portrait",
+        "ORIENTATION_SELECT_LANDSCAPE_ID" : "layout-landscape",
+        "PLATFORM_SELECT_ID": "platform-select",
+        "DEVICE_SELECT_ID": "device-select",
+        "STORAGE_TABLE_BODY_CLASS": "preferences-list-body",
+        "STORAGE_COUNT_CONTAINER_ID": "preferences-count",
+        "GEO_MAP_CONTAINER_ID": "geo-map",
+        "FILESYSTEM_UPDATE_BUTTON_ID_WITH_HASH": "#update-filesystem-button",
+        "USER_AGENT_DEFAULT": "default",
+        "APPLICATIONS_CONTAINER_ID": "widget-applications-content",
+        "STORAGE_CLEAR_BUTTON_ID": "preferences-clear-button",
+        "CHANGE_PLATFORM_BUTTON_ID": "change-platform",
+        "AJAX_LOADER_CONTAINER_CLASS": ".loader",
+        "IRRELEVANT_CLASS": "irrelevant",
+        "MULTIMEDIA_VOLUME_SLIDER_ID": "media-volume",
+        "MULTIMEDIA_VOLUME_FIELD_ID": "media-volume-value",
+        "MULTIMEDIA_AUDIO_STATE_FIELD_ID": "media-audio-state",
+        "MULTIMEDIA_AUDIO_PLAYING_FIELD_ID": "multimedia-isaudioplaying",
+        "MULTIMEDIA_AUDIO_PROGRESS_ID": "media-audio-progress",
+        "MULTIMEDIA_AUDIO_FILE_FIELD_ID": "media-audio-file",
+        "MULTIMEDIA_VIDEO_STATE_FIELD_ID": "media-video-state",
+        "MULTIMEDIA_VIDEO_PLAYING_FIELD_ID": "multimedia-isvideoplaying",
+        "MULTIMEDIA_VIDEO_PROGRESS_ID": "media-video-progress",
+        "MULTIMEDIA_VIDEO_FILE_FIELD_ID": "media-video-file",
+        "EXTENSION_URL_CONTAINER": "extension-url",
+        "SECURITY_LEVEL": "security-level"
+    },
+
+    "FILESYSTEM": {
+        "PERSISTENCE_KEY": "filesystem",
+        "INPUT_PREFIX_ID": "#panel-filesystem-"
+    },
+
+    "PLATFORM":  {
+        "SAVED_KEY": "api-key",
+        "DEFAULT": {
+            "name": "tizen",
+            "version": "1.0"
+        }
+    },
+
+    "DEVICE":  {
+        "SAVED_KEY": "device-key"
+    },
+
+    "BATTERY":  {
+        "TIME": "charging-time",
+        "VOLUME": "battery-volume",
+        "CHARGING": "is-charging"
+    },
+
+    "TOUCHEVENT":  {
+        "OPTION": "touch_option",
+        "ALTKEY": "touch_altKey",
+        "METAKEY": "touch_metaKey",
+        "CTRLKEY": "touch_ctrlKey",
+        "SHIFTKEY": "touch_shiftKey",
+        "CANVAS": "touch_canvas"
+    },
+
+    "ENCAPSULATOR":  {
+        "DEFAULT_HEIGHT": 684,
+        "DEFAULT_WIDTH": 480,
+        "LAYOUT": "layout",
+        "DISPLAY_LAYOUT": {
+            "LANDSCAPE": "landscape",
+            "PORTRAIT": "portrait"
+        },
+        "ZOOMING": "screen-zooming"
+    },
+
+    "GEO":  {
+        "OPTIONS" : {
+            "LATITUDE" : "geo-latitude",
+            "LONGITUDE" : "geo-longitude",
+            "ALTITUDE" : "geo-altitude",
+            "CELL_ID" : "geo-cellid",
+            "ACCURACY" : "geo-accuracy",
+            "ALTITUDE_ACCURACY" : "geo-altitudeaccuracy",
+            "HEADING" : "geo-heading",
+            "SPEED" : "geo-speed",
+            "TIME_STAMP" : "geo-timestamp",
+            "DELAY" : "geo-delay",
+            "DELAY_LABEL" : "geo-delay-label",
+            "HEADING_LABEL" : "geo-heading-label",
+            "HEADING_MAP_LABEL" : "geo-map-direction-label",
+            "IMAGE" : "geo-map-img",
+            "MAP_CONTAINER" : "geo-map-container",
+            "TIMEOUT" : "geo-timeout",
+
+        },
+        "MAP_ZOOM_MAX": 18,
+        "MAP_ZOOM_MIN": 0,
+        "MAP_ZOOM_LEVEL_CONTAINER": "geo-map-zoomlevel-value",
+        "MAP_ZOOM_KEY": "geo-map-zoom-key"
+    },
+
+    "PUSH": {
+        "OPTIONS" : {
+            "PAYLOAD" : "push-text"
+        }
+    },
+
+    "TELEPHONY": {
+        "CALL_LIST_KEY": "telephony-call-list-key"
+    },
+
+    "PIM": {
+        "ADDRESS_LIST_KEY": "pim-address-list-key",
+        "CALENDAR_LIST_KEY": "pim-calendar-list-key"
+    },
+
+    "CAMERA": {
+        "WINDOW_ANIMATION": "images/tizen-wave.gif",
+        "WARNING_TEXT": "The runtime simulated saving the camera file to {file}. If you need to access this file in your application, please copy a file to the saved location"
+    },
+
+    "AUDIOPLAYER" : {
+        "WARNING_TEXT": "The runtime simulated saving the audio file to {file}. If you need to access this file in your application, please copy a file to the saved location"
+    },
+
+    "API_APPLICATION": {
+        "NO_APPLICATIONS_MESSAGE": "No applications available for your platform"
+    },
+
+    "NOTIFICATIONS":  {
+        "MESSAGE_CONTAINER_CLASS": "notification-message-div",
+        "MAIN_CONTAINER_CLASS": "panel-notification",
+        "CLOSE_BUTTON_CLASS": "panel-notification-closebtn",
+        "MESSAGE_TEXT_CONTAINER_CLASS": "panel-notification-text",
+        "CSS_PREFIX": "panel-notification-",
+        "STATE_TYPES": {
+            "OPEN": 1,
+            "CLOSE": 2
+        }
+    },
+
+    "CSS_PREFIX":  {
+        "IRRELEVANT" : "irrelevant"
+    },
+
+    "STORAGE":  {
+        "PAIR_DELIMETER" : ",",
+        "KEY_VALUE_DELIMETER" : "|"
+    },
+
+    "REGEX":  {
+        "GEO" : /^geo-/,
+        "URL": /^((https?|ftp|gopher|telnet|file|notes|ms-help):((\/\/)|(\\\\))+[\w\d:#@%\/;$()~_?\+-=\\\.&]*)$/,
+        //"Email": /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/
+        "EMAIL": /^([^@\s]+)@((?:[\-a-z0-9]+\.)+[a-z]{2,})$/,
+        "WC3_DTF": /^((\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)|(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)|(\d{4})-(\d\d)-(\d\d)|(\d{4})-(\d\d)|(\d\d\d\d))$/,
+        "LOCAL_URI": /^https?:\/\/(127\.0\.0\.1|localhost)|^file:\/\//,
+        "EXTERNAL_URI": /(?:(?:[a-zA-Z0-9\/;\?&=:\-_\$\+!\*'\(\|\\~\[\]#%\.](?!www))+(?:\.[Cc]om|\.[Ee]du|\.[gG]ov|\.[Ii]nt|\.[Mm]il|\.[Nn]et|\.[Oo]rg|\.[Bb]iz|\.[Ii]nfo|\.[Nn]ame|\.[Pp]ro|\.[Aa]ero|\.[cC]oop|\.[mM]useum|\.[Cc]at|\.[Jj]obs|\.[Tt]ravel|\.[Aa]rpa|\.[Mm]obi|\.[Aa]c|\.[Aa]d|\.[aA]e|\.[aA]f|\.[aA]g|\.[aA]i|\.[aA]l|\.[aA]m|\.[aA]n|\.[aA]o|\.[aA]q|\.[aA]r|\.[aA]s|\.[aA]t|\.[aA]u|\.[aA]w|\.[aA]z|\.[aA]x|\.[bB]a|\.[bB]b|\.[bB]d|\.[bB]e|\.[bB]f|\.[bB]g|\.[bB]h|\.[bB]i|\.[bB]j|\.[bB]m|\.[bB]n|\.[bB]o|\.[bB]r|\.[bB]s|\.[bB]t|\.[bB]v|\.[bB]w|\.[bB]y|\.[bB]z|\.[cC]a|\.[cC]c|\.[cC]d|\.[cC]f|\.[cC]g|\.[cC]h|\.[cC]i|\.[cC]k|\.[cC]l|\.[cC]m|\.[cC]n|\.[cC]o|\.[cC]r|\.[cC]s|\.[cC]u|\.[cC]v|\.[cC]x|\.[cC]y|\.[cC]z|\.[dD]e|\.[dD]j|\.[dD]k|\.[dD]m|\.[dD]o|\.[dD]z|\.[eE]c|\.[eE]e|\.[eE]g|\.[eE]h|\.[eE]r|\.[eE]s|\.[eE]t|\.[eE]u|\.[fF]i|\.[fF]j|\.[fF]k|\.[fF]m|\.[fF]o|\.[fF]r|\.[gG]a|\.[gG]b|\.[gG]d|\.[gG]e|\.[gG]f|\.[gG]g|\.[gG]h|\.[gG]i|\.[gG]l|\.[gG]m|\.[gG]n|\.[gG]p|\.[gG]q|\.[gG]r|\.[gG]s|\.[gG]t|\.[gG]u|\.[gG]w|\.[gG]y|\.[hH]k|\.[hH]m|\.[hH]n|\.[hH]r|\.[hH]t^[ml]?|\.[hH]u|\.[iI]d|\.[iI]e|\.[iI]l|\.[iI]m|\.[iI]n|\.[iI]o|\.[iI]q|\.[iI]r|\.[iI]s|\.[iI]t|\.[jJ]e|\.[jJ]m|\.[jJ]o|\.[jJ]p|\.[kK]e|\.[kK]g|\.[kK]h|\.[kK]i|\.[kK]m|\.[kK]n|\.[kK]p|\.[kK]r|\.[kK]w|\.[kK]y|\.[kK]z|\.[lL]a|\.[lL]b|\.[lL]c|\.[lL]i|\.[lL]k|\.[lL]r|\.[lL]s|\.[lL]t|\.[lL]u|\.[lL]v|\.[lL]y|\.[mM]a|\.[mM]c|\.[mM]d|\.[mM]g|\.[mM]h|\.[mM]k|\.[mM]l|\.[mM]m|\.[mM]n|\.[mM]o|\.[mM]p|\.[mM]q|\.[mM]r|\.[mM]s|\.[mM]t|\.[mM]u|\.[mM]v|\.[mM]w|\.[mM]x|\.[mM]y|\.[mM]z|\.[nN]a|\.[nN]c|\.[nN]e|\.[nN]f|\.[nN]g|\.[nN]i|\.[nN]l|\.[nN]o|\.[nN]p|\.[nN]r|\.[nN]u|\.[nN]z|\.[oO]m|\.[pP]a|\.[pP]e|\.[pP]f|\.[pP]g|\.[pP]h|\.[pP]k|\.[pP]l|\.[pP]m|\.[pP]n|\.[pP]r|\.[pP]s|\.[pP]t|\.[pP]w|\.[pP]y|\.[qP]a|\.[rR]e|\.[rR]o|\.[rR]u|\.[rR]w|\.[sS]a|\.[sS]b|\.[sS]c|\.[sS]d|\.[sS]e|\.[sS]g|\.[sS]h|\.[Ss]i|\.[sS]j|\.[sS]k|\.[sS]l|\.[sS]m|\.[sS]n|\.[sS]o|\.[sS]r|\.[sS]t|\.[sS]v[^c]|\.[sS]y|\.[sS]z|\.[tT]c|\.[tT]d|\.[tT]f|\.[tT]g|\.[tT]h|\.[tT]j|\.[tT]k|\.[tT]l|\.[tT]m|\.[tT]n|\.[tT]o|\.[tT]p|\.[tT]r|\.[tT]t|\.[tT]v|\.[tT]w|\.[tT]z|\.[uU]a|\.[uU]g|\.[uU]k|\.[uU]m|\.[uU]s|\.[uU]y|\.[uU]z|\.[vV]a|\.[vV]c|\.[vV]e|\.[vV]g|\.[vV]i|\.[vV]n|\.[vV]u|\.[wW]f|\.[wW]s|\.[yY]e|\.[yY]t|\.[yY]u|\.[zZ]a|\.[zZ]m|\.[zZ]w))/
+    },
+
+    "CONFIG": {
+        "SUCCESS_CSS": {
+            "true": "ui-text-pass",
+            "false": "ui-text-fail",
+            "missing": "ui-text-missing"
+        }
+    },
+
+    "SETTINGS": {
+        "TOOLTIPS_TOGGLE_DIV": "#settings-toggletooltips",
+        "TOOLTIPS_KEY": "tool-tips-key"
+    },
+
+    "PANEL": {
+        "PANEL_CONFIG_ENABLE": "panel-config-enable"
+    },
+
+    "UI": {
+        "JQUERY_UI_BUTTON_CLASSES": "ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only",
+        "JQUERY_UI_INPUT_CLASSES": "ui-state-default ui-corner-all",
+        "PANEL_TABLE_CLASS": "panel-table",
+        "RIGHT_RANGE_LABEL_CLASS": "range-label",
+        "LEFT_RANGE_LABEL_CLASS": "range-label-left",
+        "TEXT_LABEL_CLASS": "ui-text-label",
+        "SCREEN_PPI": 96
+    },
+
+    "MULTIMEDIA": {
+        "AUDIO_STATES": {
+            "OPENED": "opened",
+            "STOPPED": "stopped",
+            "PAUSED": "paused",
+            "PLAYING": "playing",
+            "COMPLETED": "completed"
+        }
+    },
+
+    "LANG": {
+        "ISO6392_LIST": ["abk", "ace", "ach", "ada", "ady", "aar", "afh", "afr", "afa", "ain", "aka", "akk", "alb/sqi", "gsw", "ale", "alg", "tut", "amh", "anp", "apa", "ara", "arg", "arp", "arw", "arm/hye", "rup", "art", "asm", "ast", "ath", "aus", "map", "ava", "ave", "awa", "aym", "aze", "ban", "bat", "bal", "bam", "bai", "bad", "bnt", "bas", "bak", "baq/eus", "btk", "bej", "bel", "bem", "ben", "ber", "bho", "bih", "bik", "byn", "bin", "bis", "zbl", "nob", "bos", "bra", "bre", "bug", "bul", "bua", "bur/mya", "cad", "spa", "cat", "cau", "ceb", "cel", "cai", "khm", "chg", "cmc", "cha", "che", "chr", "nya", "chy", "chb", "chi/zho", "chn", "chp", "cho", "zha", "chu", "chk", "chv", "nwc", "syc", "rar", "cop", "cor", "cos", "cre", "mus", "crp", "cpe", "cpf", "cpp", "crh", "hrv", "cus", "cze/ces", "dak", "dan", "dar", "del", "div", "zza", "din", "doi", "dgr", "dra", "dua", "dut/nld", "dum", "dyu", "dzo", "frs", "efi", "egy", "eka", "elx", "eng", "enm", "ang", "myv", "epo", "est", "ewe", "ewo", "fan", "fat", "fao", "fij", "fil", "fin", "fiu", "fon", "fre/fra", "frm", "fro", "fur", "ful", "gaa", "gla", "car", "glg", "lug", "gay", "gba", "gez", "geo/kat", "ger/deu", "nds", "gmh", "goh", "gem", "kik", "gil", "gon", "gor", "got", "grb", "grc", "gre/ell", "kal", "grn", "guj", "gwi", "hai", "hat", "hau", "haw", "heb", "her", "hil", "him", "hin", "hmo", "hit", "hmn", "hun", "hup", "iba", "ice/isl", "ido", "ibo", "ijo", "ilo", "arc", "smn", "inc", "ine", "ind", "inh", "ina", "ile", "iku", "ipk", "ira", "gle", "mga", "sga", "iro", "ita", "jpn", "jav", "kac", "jrb", "jpr", "kbd", "kab", "xal", "kam", "kan", "kau", "pam", "kaa", "krc", "krl", "kar", "kas", "csb", "kaw", "kaz", "kha", "khi", "kho", "kmb", "kin", "kir", "tlh", "kom", "kon", "kok", "kor", "kos", "kpe", "kro", "kua", "kum", "kur", "kru", "kut", "lad", "lah", "lam", "day", "lao", "lat", "lav", "ltz", "lez", "lim", "lin", "lit", "jbo", "dsb", "loz", "lub", "lua", "lui", "smj", "lun", "luo", "lus", "mac/mkd", "mad", "mag", "mai", "mak", "mlg", "may/msa", "mal", "mlt", "mnc", "mdr", "man", "mni", "mno", "glv", "mao/mri", "arn", "mar", "chm", "mah", "mwr", "mas", "myn", "men", "mic", "min", "mwl", "moh", "mdf", "rum/ron", "mkh", "lol", "mon", "mos", "mul", "mun", "nqo", "nah", "nau", "nav", "nde", "nbl", "ndo", "nap", "new", "nep", "nia", "nic", "ssa", "niu", "zxx", "nog", "non", "nai", "frr", "sme", "nso", "nor", "nno", "nub", "iii", "nym", "nyn", "nyo", "nzi", "oci", "pro", "oji", "ori", "orm", "osa", "oss", "oto", "pal", "pau", "pli", "pag", "pan", "pap", "paa", "pus", "per/fas", "peo", "phi", "phn", "pon", "pol", "por", "pra", "que", "raj", "rap", "qaa-qtz", "roa", "roh", "rom", "run", "rus", "sal", "sam", "smi", "smo", "sad", "sag", "san", "sat", "srd", "sas", "sco", "sel", "sem", "srp", "srr", "shn", "sna", "scn", "sid", "sgn", "bla", "snd", "sin", "sit", "sio", "sms", "den", "sla", "slo/slk", "slv", "sog", "som", "son", "snk", "wen", "sot", "sai", "alt", "sma", "srn", "suk", "sux", "sun", "sus", "swa", "ssw", "swe", "syr", "tgl", "tah", "tai", "tgk", "tmh", "tam", "tat", "tel", "ter", "tet", "tha", "tib/bod", "tig", "tir", "tem", "tiv", "tli", "tpi", "tkl", "tog", "ton", "tsi", "tso", "tsn", "tum", "tup", "tur", "ota", "tuk", "tvl", "tyv", "twi", "udm", "uga", "uig", "ukr", "umb", "mis", "und", "hsb", "urd", "uzb", "vai", "ven", "vie", "vol", "vot", "wak", "wln", "war", "was", "wel/cym", "fry", "wal", "wol", "xho", "sah", "yao", "yap", "yid", "yor", "ypk", "znd", "zap", "zen", "zul", "zun"]
+    },
+
+    "XHR": {
+        "PROXY_DISABLED_BUTTON": "settings-xhrproxy-disabled"
+    },
+
+    "PLATFORMS": {
+        "WAC": {
+            "APPLICATIONS": [
+                "ALARM",
+                "BROWSER",
+                "CALCULATOR",
+                "CALENDAR",
+                "CAMERA",
+                "CONTACTS",
+                "FILES",
+                "GAMES",
+                "MAIL",
+                "MEDIAPLAYER",
+                "MESSAGING",
+                "PHONECALL",
+                "PICTURES",
+                "PROG_MANAGER",
+                "SETTINGS",
+                "TASKS",
+                "WIDGET_MANAGER"
+            ],
+            "DEVICE": {
+                "WIDGET_ENGINE_NAME": "Generic",
+                "WIDGET_ENGINE_PROVIDER": "tinyHippos",
+                "WIDGET_ENGINE_VERSION": "x.x"
+            }
+        }
+    },
+
+    "POWER_RESOURCE": {
+        "CPU": {
+            "NAME": "CPU",
+            "STATE": {
+                "LOW": {
+                    "NAME": "LOW",
+                    "MIN": 0,
+                    "MAX": 0.5,
+                    "VALUE": 0.3
+                },
+                "HIGH": {
+                    "NAME": "HIGH",
+                    "MIN": 0.5,
+                    "MAX": 1,
+                    "VALUE": 0.7
+                }
+            }
+            
+        },
+        "DISPLAY": {
+            "NAME": "DISPLAY",
+            "STATE": {
+                "OFF": {
+                    "NAME": "OFF",
+                    "MIN": 0,
+                    "MAX": 0,
+                    "VALUE": 0
+                },
+                "DIM": {
+                    "NAME": "DIM",
+                    "MIN": 0,
+                    "MAX": 0.5,
+                    "VALUE": 0.3
+                },
+                "NORMAL": {
+                    "NAME": "NORMAL",
+                    "MIN": 0.5,
+                    "MAX": 0.7,
+                    "VALUE": 0.6
+                },
+                "BRIGHT": {
+                    "NAME": "BRIGHT",
+                    "MIN": 0.7,
+                    "MAX": 1,
+                    "VALUE": 0.9
+                }
+            }
+            
+        }
+    },
+    
+    "POWER_RULES": {
+        "LOW": true,
+        "HIGH": true,
+        "OFF": true,
+        "DIM": true,
+        "NORMAL": true,
+        "BRIGHT": true
+    }
+};
+
+});
+require.define('ripple/deviceMotionEmulator', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var event = require('ripple/event'),
+    platform = require('ripple/platform'),
+    INTERVAL = 60000,
+    _self;
+
+function _bind(name, win) {
+    var callback = null;
+
+    win.__defineGetter__(name, function () {
+        return callback;
+    });
+
+    win.__defineSetter__(name, function (cb) {
+        callback = cb;
+    });
+
+    return {
+        get: function () {
+            return callback;
+        },
+        set: function (value) {
+            callback = value;
+        },
+        exec: function (arg) {
+            return callback && callback(arg);
+        },
+        unbind: function (cb) {
+            callback = cb === callback ? null : callback;
+        }
+    };
+}
+
+_self = {
+    init: function (frame) {
+        var widgetWindow = frame.contentWindow,
+            _motion,
+            _orientation,
+            _calibration,
+            add = widgetWindow.addEventListener,
+            remove = widgetWindow.removeEventListener;
+
+        //Hang events off window (these are used to check for API existence by developer)
+        widgetWindow.DeviceMotionEvent = function DeviceMotionEvent() {};
+        widgetWindow.DeviceOrientationEvent = function DeviceOrientationEvent() {};
+
+        _motion = _bind("ondevicemotion", widgetWindow);
+        _orientation = _bind("ondeviceorientation", widgetWindow);
+        _calibration = _bind("oncompassneedscalibration", widgetWindow);
+
+        widgetWindow.addEventListener = function (event, callback, useCapture) {
+            switch (event) {
+            case "deviceorientation":
+                _orientation.set(callback);
+                break;
+
+            case "devicemotion":
+                _motion.set(callback);
+                break;
+
+            case "compassneedscalibration":
+                _calibration.set(callback);
+                break;
+
+            default:
+                add.apply(widgetWindow, arguments);
+                break;
+            }
+        };
+
+        widgetWindow.removeEventListener = function (event, callback) {
+            _motion.unbind(callback);
+            _orientation.unbind(callback);
+            remove.apply(widgetWindow, arguments);
+        };
+
+        event.on("DeviceMotionEvent", function (motion) {
+            var _motionEvent, DeviceMotionEvent;
+
+            if (platform.current().DeviceMotionEvent) {
+                DeviceMotionEvent = platform.current().DeviceMotionEvent;
+                if (typeof DeviceMotionEvent !== "function")
+                    return;
+
+                _motionEvent = new DeviceMotionEvent();
+                _motionEvent.initAccelerometerEvent("devicemotion", true, false, motion.acceleration, motion.accelerationIncludingGravity, 
+                                                    motion.rotationRate, INTERVAL);    
+            }
+            else {
+                _motionEvent = {
+                    acceleration: motion.acceleration,
+                    accelerationIncludingGravity: motion.accelerationIncludingGravity,
+                    rotationRate: motion.rotationRate
+                };
+            }
+
+            _motion.exec(_motionEvent);
+        });
+
+        event.on("DeviceOrientationEvent", function (motion) {
+            var _orientationEvent, DeviceOrientationEvent;
+
+            if (platform.current().DeviceOrientationEvent) {
+                DeviceOrientationEvent = platform.current().DeviceOrientationEvent;
+                if (typeof DeviceOrientationEvent !== "function")
+                    return;
+
+                _orientationEvent = new DeviceOrientationEvent();        
+                _orientationEvent.initDeviceOrientationEvent("deviceorientation", true, false, motion.orientation.alpha, 
+                                                              motion.orientation.beta, motion.orientation.gamma, true);
+            }
+            else {
+                _orientationEvent = motion.orientation;
+            }
+
+            _orientation.exec(_orientationEvent);
+        });
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/console', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self;
+
+function _log(msg, method) {
+    try {
+        console[method](_self.prefix ? _self.prefix + " :: " + msg : msg);
+    } catch (e) {
+        // silent
+    }
+}
+
+_self = {
+    log: function (msg) {
+        _log(msg, "log");
+    },
+
+    warn: function (msg) {
+        _log(msg, "warn");
+    },
+
+    error: function (msg) {
+        _log(msg, "error");
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/geo', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var db = require('ripple/db'),
+    exception = require('ripple/exception'),
+    event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    _positionInfo = {
+        "latitude": 39.968362,
+        "longitude": 116.410186,
+        "altitude": 50,
+        "accuracy": 150,
+        "altitudeAccuracy": 80,
+        "heading": 0,
+        "speed": 0,
+        "cellID": 1130433
+    },
+    self;
+
+function _serialize(settings) {
+    var tempSettings = utils.copy(settings);
+    tempSettings.position.timeStamp = "new Date(" + tempSettings.position.timeStamp.getTime() + ")";
+    return tempSettings;
+}
+
+function _validatePositionInfo(pInfo) {
+    return (pInfo &&
+        !(isNaN(pInfo.latitude) ||
+        isNaN(pInfo.longitude) ||
+        isNaN(pInfo.altitude) ||
+        isNaN(pInfo.accuracy) ||
+        isNaN(pInfo.altitudeAccuracy) ||
+        isNaN(pInfo.heading) ||
+        isNaN(pInfo.speed) ||
+        isNaN(pInfo.cellID))) ? true : false;
+}
+
+self = module.exports = {
+    initialize: function () {
+        var settings = db.retrieveObject("geosettings");
+        if (settings) {
+            utils.forEach(_positionInfo, function (value, key) {
+                _positionInfo[key] = parseFloat(settings.position[key] || value);
+            });
+
+            self.timeout = settings.timeout;
+            self.delay = settings.delay || 0;
+
+        }
+    },
+
+    getPositionInfo: function () {
+        var pi = utils.copy(_positionInfo);
+        pi.timeStamp = new Date();
+
+        return pi;
+    },
+
+    updatePositionInfo: function (newPositionInfo, delay, timeout) {
+        if (!_validatePositionInfo(newPositionInfo)) {
+            exception.raise(exception.types.Geo, "invalid positionInfo object");
+        }
+
+        _positionInfo = utils.copy(newPositionInfo);
+        _positionInfo.timeStamp = new Date();
+
+        self.delay = delay || 0;
+        self.timeout = timeout;
+
+        db.saveObject("geosettings", _serialize({
+            position: _positionInfo,
+            delay: self.delay,
+            timeout: self.timeout
+        }));
+
+        event.trigger("PositionInfoUpdatedEvent", [_positionInfo]);
+    },
+
+    timeout: false,
+    delay: 0,
+    map: {}
+};
+
+});
+require.define('ripple/ui', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _self,
+    db = require('ripple/db'),
+    platform = require('ripple/platform'),
+    constants = require('ripple/constants'),
+    utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    event = require('ripple/event'),
+    _applicationStateId,
+    _applicationState,
+    _availablePanels,
+    _applicationStateTmp,
+    _panelConfigEnabled,
+    _systemPlugins = [
+        "options",
+        "about-dialog",
+        "settings-dialog",
+        "firstRunCheck",
+        "devices",
+        "goodVibrations",
+        "panelCollapse",
+        "platform",
+        "information",
+        "layout",
+        "notifications",
+        "themeSwitcher",
+        "settings-menu"
+    ],
+    _overlay = {
+        getOrCreate: function (id) {
+            var _container = document.getElementById(constants.COMMON.HTML_CONTAINER),
+                _overlays = document.getElementById("overlay-views"),
+                _overlay = _overlays.children[id],
+                _hide = function (node) {
+                    node.setAttribute("style", "display: none");
+                },
+                _show = function (node) {
+                    node.setAttribute("style", "display: block");
+                },
+                _trigger = function (callback) {
+                    if (callback) {
+                        callback.apply(null, [_overlay]);
+                    }
+                };
+
+
+            if (!_overlay) {
+                _overlay = utils.createElement("section", {id: id, "class": "overlay"});
+                _overlays.appendChild(_overlay);
+            }
+
+            return {
+                hide: function (callback) {
+                    _hide(_overlay);
+                    _show(_container);
+                    _trigger(callback);
+                },
+                show: function (callback, showContainer) {
+                    _show(_overlay);
+                    if (!showContainer) {
+                        _hide(_container);
+                    }
+                    _trigger(callback);
+                }
+            };
+        }
+    };
+
+function _addUIPaneItemsToApplicationState(arrayObj, pane) {
+    utils.forEach(arrayObj, function (domId) {
+        var collapsed = jQuery("#" + domId + " .info")[0];
+        collapsed = (collapsed.style && collapsed.style.display === "none") ? true : false;
+        utils.forEach(_applicationStateTmp, function (obj) {
+            if (obj.domId === domId) {
+                _applicationState.push({
+                    "domId": domId,
+                    "collapsed": collapsed,
+                    "pane": pane,
+                    "titleName" : obj.titleName,
+                    "display" : obj.display
+                });
+                _applicationStateTmp.splice(_applicationStateTmp.indexOf(obj), 1);
+                return;
+            }
+        }, this);
+    }, this);
+
+    utils.forEach(_applicationStateTmp, function (obj) {
+        _applicationState.push({
+            "domId": obj.domId,
+            "collapsed": obj.collapsed,
+            "pane": obj.pane,
+            "titleName" : obj.titleName,
+            "display" : obj.display
+        });
+    });
+}
+
+function _insertStyleSheets() {
+    var uiTheme = db.retrieve("ui-theme") || require('ripple/ui/themes')[0],
+        extensionURL = jQuery("#extension-url").text(),
+        uiThemeURL = extensionURL + "themes/" + uiTheme + "/theme.css",
+        head = document.getElementsByTagName('head')[0];
+
+    function stylesheet(src) {
+        var scriptElement = document.createElement("link");
+        scriptElement.setAttribute("href", src);
+        scriptElement.setAttribute("type", "text/css");
+        scriptElement.setAttribute("rel", "stylesheet");
+        return scriptElement;
+    }
+
+    head.appendChild(stylesheet(uiThemeURL));
+}
+
+function _collapsePannels(side) {
+    var collapseNode = [],
+        event = document.createEvent("UIEvent");
+
+    collapseNode = side === "left" ? document.getElementsByClassName("left-panel-collapse") : 
+                                     document.getElementsByClassName("right-panel-collapse");
+    
+    if (collapseNode.length > 0) {
+        event.initEvent("click", true, true);
+        collapseNode[0].dispatchEvent(event);    
+    }
+}
+
+function _initializeUI() {
+    _applicationStateId = constants.COMMON.APPLICATION_STATE +
+        ((db.retrieveObject(constants.PLATFORM.SAVED_KEY) || constants.PLATFORM.DEFAULT)).name;
+
+    _applicationState = db.retrieveObject(_applicationStateId) || [];
+    _panelConfigEnabled = db.retrieveObject(constants.PANEL.PANEL_CONFIG);
+
+    _insertStyleSheets();
+
+    var leftPanelSection = jQuery(".left"),
+        uiBoxToggleEngaged = false;
+
+    //clean up
+    db.remove("ui-application-state");
+
+    if (!_panelConfigEnabled) {
+        _applicationState = [];
+        _panelConfigEnabled = true;
+    }
+
+    utils.forEach(_availablePanels, function (obj) {
+        var matchingDomId = function (panel) {
+            return panel.domId === obj.domId;
+        };
+        if (!utils.some(_applicationState, matchingDomId)) {
+            _applicationState.push({
+                "domId": obj.domId,
+                "collapsed": obj.collapsed,
+                "pane": obj.pane,
+                "titleName" : obj.titleName,
+                "display" : obj.display
+            });
+        }
+    });
+
+    utils.forEach(_applicationState, function (obj) {
+        var node = jQuery("#" + obj.domId),
+            imgNode = node.find(".ui-box-TitleImage");
+            matchingDomId = function (panel) {
+                return panel.domId === obj.domId;
+            };
+
+        if (node.length > 0) {
+            if (!utils.some(_availablePanels, matchingDomId)) {
+                node.parent()[0].removeChild(node[0]);
+            }
+            else {
+                if (obj.display !== false) {
+                    leftPanelSection.append(node.parent()[0].removeChild(node[0]));
+                    if (!obj.collapsed) {
+                        node.find(".info")
+                            .css({
+                            "display": "block"
+                        })
+                        .end()
+                        .addClass("ui-box-open");
+                        imgNode.addClass("ui-box-TitleImageOpen");
+                    }
+                }
+            }
+        }
+    });
+
+    db.saveObject(_applicationStateId, _applicationState);
+    db.saveObject(constants.PANEL.PANEL_CONFIG, _panelConfigEnabled);
+
+    event.on("ApplicationState", function () {
+        try {
+            var leftArray = jQuery(".left").sortable('toArray');
+            _applicationStateTmp = [];
+            _applicationStateTmp = utils.copy(_applicationState);
+            _applicationState = [];
+            _addUIPaneItemsToApplicationState(leftArray, "left");
+
+            if (leftArray.length === 0) {
+                _collapsePannels("left");
+            }
+
+            db.saveObject(_applicationStateId, _applicationState);
+        }
+        catch (e) {
+            exception.handle(e);
+        }
+    });
+
+    jQuery(".left").sortable({
+        handle: ".drag-handle",
+        revert: true,
+        placeholder: 'ui-sortable-highlight ui-corner-all',
+        connectWith: [".left"],
+        scroll: true,
+        update: function (uiEvent, ui) {
+            event.trigger("ApplicationState");
+        }
+    });
+
+    jQuery(".left").sortable({ axis: 'y' });
+
+    jQuery(".collapse-handle").bind("click", function () {
+        if (!uiBoxToggleEngaged) {
+
+            uiBoxToggleEngaged = true;
+
+            var jNode = jQuery(this).parentsUntil(".ui-box"),
+                    pNode = jNode.parent(),
+                    isOpen = pNode.hasClass("ui-box-open"),
+                    imgNode = jQuery(this).find(".ui-box-TitleImage");
+
+            if (!isOpen) {
+                pNode.addClass("ui-box-open");
+                imgNode.removeClass("ui-box-TitleImageClosed");
+                imgNode.addClass("ui-box-TitleImageOpen");
+            }
+
+            jQuery(this).parent().next().toggle("blind", {}, 300, function () {
+                if (isOpen) {
+                    pNode.removeClass("ui-box-open");
+                    imgNode.removeClass("ui-box-TitleImageOpen");
+                    imgNode.addClass("ui-box-TitleImageClosed");
+                }
+                event.trigger("ApplicationState", [pNode]);
+                uiBoxToggleEngaged = false;
+            });
+        }
+    });
+}
+
+_self = module.exports = {
+    initialize: function () {
+        var plugins = _systemPlugins.concat(platform.current().ui.plugins || []).map(function (name) {
+                return require('ripple/ui/plugins/' + name);
+            }),
+            boot = jWorkflow.order(_initializeUI);
+
+        _availablePanels = [];
+
+        plugins.forEach(function (plugin) {
+            if (plugin.initialize) {
+                boot.andThen(plugin.initialize);
+            }
+
+            if (plugin.panel) {
+                _availablePanels.push(plugin.panel);
+            }
+        });
+
+        boot.start();
+    },
+
+    getSystemPlugins: function () {
+        return utils.copy(_systemPlugins);
+    },
+
+    register: function (plugin) {
+        _systemPlugins.push(plugin);
+    },
+
+    registered: function (plugin) {
+        return _systemPlugins.indexOf(plugin) >= 0;
+    },
+
+    getExtensionURL: function () {
+        return jQuery("#" + constants.COMMON.EXTENSION_URL_CONTAINER).text();
+    },
+
+    showOverlay: function (id, callback, showContainer) {
+        _overlay.getOrCreate(id).show(callback, showContainer);
+    },
+
+    hideOverlay: function (id, callback) {
+        _overlay.getOrCreate(id).hide(callback);
+    }
+};
+
+});
+require.define('ripple/utils', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var self,
+    exception = require('ripple/exception'),
+    constants = require('ripple/constants'),
+    _HtmlElements = ['header', 'footer', 'section', 'aside', 'nav', 'article'];
+
+self = module.exports = {
+    validateNumberOfArguments: function (lowerBound, upperBound, numberOfArguments, customExceptionType, customExceptionMessage, customExceptionObject) {
+
+        customExceptionMessage = customExceptionMessage || "";
+
+        if (arguments.length < 3 || arguments.length > 6) {
+            exception.raise(exception.types.Argument, "Wrong number of arguments when calling: validateNumberOfArguments()");
+        }
+
+        if (isNaN(lowerBound) && isNaN(upperBound) && isNaN(numberOfArguments)) {
+            exception.raise(exception.types.ArgumentType, "(validateNumberOfArguments) Arguments are not numbers");
+        }
+
+        lowerBound = parseInt(lowerBound, 10);
+        upperBound = parseInt(upperBound, 10);
+        numberOfArguments = parseInt(numberOfArguments, 10);
+
+        if (numberOfArguments < lowerBound || numberOfArguments > upperBound) {
+            exception.raise((customExceptionType || exception.types.ArgumentLength), (customExceptionMessage + "\n\nWrong number of arguments"), customExceptionObject);
+        }
+
+    },
+
+    validateArgumentType: function (arg, argType, customExceptionType, customExceptionMessage, customExceptionObject) {
+        var invalidArg = false,
+            msg;
+
+        switch (argType) {
+        case "array":
+            if (!arg instanceof Array) {
+                invalidArg = true;
+            }
+            break;
+        case "date":
+            if (!arg instanceof Date) {
+                invalidArg = true;
+            }
+            break;
+        case "integer":
+            if (typeof arg === "number") {
+                if (arg !== Math.floor(arg)) {
+                    invalidArg = true;
+                }
+            }
+            else {
+                invalidArg = true;
+            }
+            break;
+        default:
+            if (typeof arg !== argType) {
+                invalidArg = true;
+            }
+            break;
+        }
+
+        if (invalidArg) {
+            msg = customExceptionMessage +  ("\n\nInvalid Argument type. argument: " + arg + " ==> was expected to be of type: " + argType);
+            exception.raise((customExceptionType || exception.types.ArgumentType), msg, customExceptionObject);
+        }
+    },
+
+    validateMultipleArgumentTypes: function (argArray, argTypeArray, customExceptionType, customExceptionMessage, customExceptionObject) {
+        for (var i = 0; i < argArray.length; i++) {
+            this.validateArgumentType(argArray[i], argTypeArray[i], customExceptionType, customExceptionMessage, customExceptionObject);
+        }
+    },
+
+    createElement: function (elementType, attributes) {
+        var d = document.createElement(elementType);
+
+        if (attributes) {
+            this.forEach(attributes, function (attributeValue, attributeName) {
+
+                switch (attributeName.toLowerCase()) {
+
+                case "innerhtml":
+                    d.innerHTML = attributeValue;
+                    break;
+
+                case "innertext":
+                    d.innerText = attributeValue;
+                    break;
+
+                default:
+                    d.setAttribute(attributeName, attributeValue);
+                }
+
+            });
+        }
+
+        return d;
+    },
+
+
+    loadHTMLElements: function () {
+        for (var i = 0; i < _HtmlElements.length; i += 1) {
+            document.createElement(_HtmlElements[i]);
+        }
+    },
+
+    getAllStylesheetRules: function getAllStylesheetRules(title) {
+        this.validateNumberOfArguments(1, 1, arguments.length);
+
+        var i, x, sheet, rules, styles_array = [];
+
+        // get style sheet according to title
+        for (i = 0; i < document.styleSheets.length; i += 1) {
+
+            sheet = document.styleSheets[i];
+            rules = sheet.cssRules;
+
+            if (rules) {
+                for (x = 0; x < rules.length; x += 1) {
+                    if (rules[x].selectorText && rules[x].selectorText === (title.toString())) {
+                        styles_array.push(rules[x]);
+                    }
+                }
+            }
+        }
+
+        return (styles_array);
+    },
+
+    location: function () {
+        return window.location;
+    },
+
+    appLocation: function () {
+        if (require('ripple/ui').registered("omnibar")) {
+            /* rootURL can only get url saved from 'FrameHistoryChange' event
+               it causes trouble when navigating directory through online 
+               version as index.html is automatically loaded.
+               Need a way to get more updated URL */
+
+            var path = require('ripple/ui/plugins/omnibar').rootURL(),
+                parts;
+
+            if ((parts = path.match(/^((http[s]?|ftp|file):\/\/)(.+\/)?([^\/].+)$/i)) !== null && parts.length === 5) {
+                // this is a path already.
+                if (path.search(/\/$/, "") !== -1) {
+                    return path;
+                }
+                if (parts[4] === "about:blank") {
+                    path = "";
+                }
+                else if (parts[3]) {
+                    path = parts[1] + parts[3];
+                    if (parts[4].indexOf(".") === -1) {
+                        path += parts[4] + "/";
+                    }
+                }
+                else {
+                    path = parts[1] + parts[4] + "/";
+                }
+            }
+            else {
+                path = "";
+            }
+            return path;
+        }
+        return self.rippleLocation();
+    },
+
+    rippleLocation: function () {
+        var loc = self.location(),
+            parts = loc.pathname.replace(/\/$/, "").split("/"),
+            base = "",
+            port = loc.port ? ":" + loc.port : "";
+
+        if (parts[parts.length - 1].indexOf(".") !== -1) {
+            parts = parts.splice(0, parts.length - 1);
+        }
+        base = parts.join("/");
+
+        return loc.protocol + "//" + loc.hostname + port + base + "/";
+    },
+
+    arrayContains: function (array, obj) {
+        var i = array.length;
+        while (i--) {
+            if (array[i] === obj) {
+                return true;
+            }
+        }
+        return false;
+    },
+
+    some: function (obj, predicate, scope) {
+        if (obj instanceof Array) {
+            return obj.some(predicate, scope);
+        }
+        else {
+            var values = self.map(obj, predicate, scope);
+
+            return self.reduce(values, function (some, value) {
+                return value ? value : some;
+            }, false);
+        }
+    },
+
+    count: function (obj) {
+        return self.sum(obj, function (total) {
+            return 1;
+        });
+    },
+
+    sum: function (obj, selector, scope) {
+        var values = self.map(obj, selector, scope);
+        return self.reduce(values, function (total, value) {
+            return total + value;
+        });
+    },
+
+    max: function (obj, selector, scope) {
+        var values = self.map(obj, selector, scope);
+        return self.reduce(values, function (max, value) {
+            return max < value ? value : max;
+        }, Number.MIN_VALUE);
+    },
+
+    min: function (obj, selector, scope) {
+        var values = self.map(obj, selector, scope);
+        return self.reduce(values, function (min, value) {
+            return min > value ? value : min;
+        }, Number.MAX_VALUE);
+    },
+
+    forEach: function (obj, action, scope) {
+        if (obj instanceof Array) {
+            return obj.forEach(action, scope);
+        }
+        else {
+            self.map(obj, action, scope);
+        }
+    },
+
+    filter: function (obj, predicate, scope) {
+        if (obj instanceof Array) {
+            return obj.filter(predicate, scope);
+        }
+        else {
+            var result = [];
+            self.forEach(obj, function (value, index) {
+                if (predicate.apply(scope, [value, index])) {
+                    result.push(value);
+                }
+
+            }, scope);
+
+            return result;
+        }
+    },
+
+    reduce: function (obj, func, init, scope) {
+        var i,
+            initial = init === undefined ? 0 : init,
+            result = initial;
+
+
+        if (obj instanceof Array) {
+            return obj.reduce(func, initial);
+        }
+        else if (obj instanceof NamedNodeMap) {
+            for (i = 0; i < obj.length; i++) {
+                result = func.apply(scope, [result, obj[i], i]);
+            }
+        }
+        else {
+            for (i in obj) {
+                if (obj.hasOwnProperty(i)) {
+                    result = func.apply(scope, [result, obj[i], i]);
+                }
+            }
+        }
+
+        return result;
+
+    },
+
+    map: function (obj, func, scope) {
+        var i,
+            returnVal = null,
+            result = [];
+
+        if (obj instanceof Array) {
+            return obj.map(func, scope);
+        }
+        else if (obj instanceof NamedNodeMap) {
+            for (i = 0; i < obj.length; i++) {
+                returnVal = func.apply(scope, [obj[i], i]);
+                result.push(returnVal);
+            }
+        }
+        else {
+            for (i in obj) {
+                if (obj.hasOwnProperty(i)) {
+                    returnVal = func.apply(scope, [obj[i], i]);
+                    result.push(returnVal);
+                }
+            }
+        }
+
+        return result;
+    },
+
+    regexSanitize: function (regexString) {
+        return regexString.replace("^", "\\^")
+                    .replace("$", "\\$")
+                    .replace("(", "\\(")
+                    .replace(")", "\\)")
+                    .replace("<", "\\<")
+                    .replace("[", "\\[")
+                    .replace("{", "\\{")
+                    .replace(/\\/, "\\\\")
+                    .replace("|", "\\|")
+                    .replace(">", "\\>")
+                    .replace(".", "\\.")
+                    .replace("*", "\\*")
+                    .replace("+", "\\+")
+                    .replace("?", "\\?");
+    },
+
+    bindAutoSaveEvent: function (node, saveCallback) {
+        var oldSetTimeoutId,
+            jNode = jQuery(node);
+
+        jNode.bind("keyup", function (event) {
+            if (event.keyCode !== 9) {
+                clearTimeout(oldSetTimeoutId);
+                oldSetTimeoutId = window.setTimeout(function () {
+                    saveCallback();
+                }, 500);
+            }
+        });
+    },
+
+    find: function (comparison, collection, startInx, endInx, callback) {
+        var results = [],
+            compare = function (s, pattern) {
+
+                if (typeof(s) !== "string" || pattern === null) {
+                    return s === pattern;
+                }
+
+                var regex = pattern.replace(/\./g, "\\.")
+                                   .replace(/\^/g, "\\^")
+                                   .replace(/\*/g, ".*")
+                                   .replace(/\\\.\*/g, "\\*");
+
+                regex = "^".concat(regex, "$");
+
+                return !!s.match(new RegExp(regex, "i"));
+            };
+
+        self.forEach(collection, function (c) {
+            var match,
+                fail = false;
+
+            self.forEach(comparison, function (value, key) {
+                if (!fail && value !== undefined) {
+
+                    if (compare(c[key], value)) {
+                        match = c;
+                    }
+                    else {
+                        fail = true;
+                        match = null;
+                    }
+                }
+            });
+
+            if (match) {
+                results.push(match);
+            }
+        });
+
+        if (callback) {
+            if (startInx === undefined) {
+                startInx = 0;
+            }
+            if (endInx === undefined) {
+                endInx = results.length;
+            }
+            if (startInx === endInx) {
+                endInx = startInx + 1;
+            }
+
+            callback.apply(null, [results.slice(startInx, endInx)]);
+        }
+    },
+
+    mixin: function (mixin, to) {
+        for (var prop in mixin) {
+            if (Object.hasOwnProperty.call(mixin, prop)) {
+                to[prop] = mixin[prop];
+            }
+        }
+        return to;
+    },
+
+    copy: function (obj) {
+        var i,
+            newObj = jQuery.isArray(obj) ? [] : {};
+
+        if (typeof obj === 'number' ||
+            typeof obj === 'string' ||
+            typeof obj === 'boolean' ||
+            obj === null ||
+            obj === undefined) {
+            return obj;
+        }
+
+        if (obj instanceof Date) {
+            return new Date(obj);
+        }
+
+        if (obj instanceof RegExp) {
+            return new RegExp(obj);
+        }
+
+        for (i in obj) {
+            if (obj.hasOwnProperty(i)) {
+                if (obj[i] && typeof obj[i] === "object") {
+                    if (obj[i] instanceof Date) {
+                        newObj[i] = obj[i];
+                    }
+                    else {
+                        newObj[i] = self.copy(obj[i]);
+                    }
+                }
+                else {
+                    newObj[i] = obj[i];
+                }
+            }
+        }
+
+        return newObj;
+    }
+};
+
+});
+require.define('ripple/dbfs', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    event = require('ripple/event'),
+    _cache = {},
+    _self;
+
+function _get(path) {
+    return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
+        return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
+    }, _cache);
+}
+
+function _getInfo(path) {
+    var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
+        name = parent.splice(parent.length - 1, 1).join(""),
+        ext = name.split(".");
+
+    return {
+        name: name,
+        extension: ext.length > 1 ? ext[ext.length - 1] : "",
+        hidden: (name.length > 0 && name[0] === ".") || false,
+        parent: parent.join("/") || "/"
+    };
+}
+
+function _set(path, obj) {
+    var parent = _cache,
+        tokens = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
+        child = tokens.splice(tokens.length - 1, 1).join("");
+
+    tokens.forEach(function (token) {
+        parent = parent.children[token];
+    });
+
+    parent.children = parent.children || {};
+    obj.properties = obj.properties || {};
+    parent.children[child] = obj;
+}
+
+function _delete(path) {
+    var parent = _cache,
+        tokens = path.replace(/^\//, '').split("/"),
+        child = tokens.splice(tokens.length - 1, 1).join("");
+
+    tokens.forEach(function (token) {
+        parent = parent.children[token];
+    });
+
+    delete parent.children[child];
+}
+
+function _save() {
+    db.saveObject("db-filesystem", _cache);
+}
+
+_self = {
+
+    initialize: function (prev, baton) {
+        _cache = db.retrieveObject("db-filesystem") || {};
+        event.trigger("FileSystemInitialized", null, true);
+    },
+
+    ls: function (path, success, error) {
+        try {
+            var dir = _get(path),
+                items = [];
+
+            if (dir) {
+                utils.forEach(dir.children, function (item) {
+                    if (!item.isDirectory) {
+                        item.file = function (callback) {
+                            callback({});
+                        };
+                    }
+                    items.push(item);
+                });
+            }
+            else {
+                items = {};
+            }
+
+            success(utils.copy(items));
+        }
+        catch (e) {
+            e.code = 1;
+            error(e);
+        }
+    },
+
+    rm: function (path, success, error, options) {
+        _delete(path);
+        _save();
+        success();
+    },
+
+    rmdir: function (path, success, error, options) {
+        _delete(path);
+        _save();
+        success();
+    },
+
+    mkdir: function (path, success, error) {
+        var entry = _get(path),
+            info = _getInfo(path);
+
+        if (!entry) {
+            _set(path, {
+                name: info.name,
+                isDirectory: true,
+                fullPath: path
+            });
+            entry = _get(path);
+        }
+        
+        _save();
+        if (entry) {
+            success(utils.copy(entry));
+        }
+        else {
+            error({code: 1});
+        }
+    },
+
+    mv: function (from, to, success, error) {
+        try {
+            var fromEntry = _get(from),
+                toInfo = _getInfo(to);
+
+            fromEntry.fullPath = to;
+            fromEntry.name = toInfo.name;
+
+            _set(to, fromEntry);
+            _delete(from);
+            _save();
+            success(utils.copy(_get(to)));
+        }
+        catch (e) {
+            e.code = 1;
+            error(e);
+        }
+    },
+
+    touch: function (path, success, error) {
+        if (!_get(path)) {
+            _set(path, {
+                fullPath: path
+            });
+        }
+        _save();
+        success(utils.copy(_get(path)));
+    },
+
+    cp: function (from, to, success, error) {
+        try {
+            var fromEntry = _get(from);
+            fromEntry.fullPath = to;
+            _set(to, fromEntry);
+            _save();
+            success(utils.copy(_get(to)));
+        }
+        catch (e) {
+            e.code = 1;
+            error(e);
+        }
+    },
+
+    stat: function (path, success, error) {
+        var entry = _get(path);
+        success(utils.copy(entry));
+    },
+
+    write: function (path, contents, success, error, options) {
+        var info = _getInfo(path);
+
+        _set(path, {
+            lastModifiedDate: new Date(),
+            name: info.name,
+            fullPath: path,
+            isDirectory: false,
+            properties: {
+                type: "",
+                size: contents.size
+            },
+            data: contents,
+            file: function (callback) {
+                callback({});
+            }
+        });
+
+        success(utils.copy(_get(path)));
+    },
+
+    read: function (path, success, error) {
+        var entry = _get(path);
+
+        if (entry) {
+            success(utils.copy(entry.data));
+        }
+        else {
+            error({code: 1});
+        }
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/platform', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _current,
+    db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    _console = require('ripple/console'),
+    constants = require('ripple/constants'),
+    app = require('ripple/app'),
+    event = require('ripple/event'),
+    spec = require('ripple/platform/spec'),
+    _self;
+
+function _checkForDeprecatedPlatforms(replacement) {
+    if (!spec[_current.name] ||
+        !spec[_current.name][_current.version] ||
+        (spec[_current.name][_current.version] && !spec[_current.name][_current.version].objects)) {
+        _current = replacement;
+        db.saveObject(constants.PLATFORM.SAVED_KEY, _current);
+    }
+}
+
+function _getPlatform() {
+    var p = require('ripple/platform/' + _current.name + "/" + _current.version + "/spec");
+    return p;
+}
+
+_self = {
+    initialize: function () {
+        var firstAvailablePlatform = utils.map(this.getList(), function (platform) {
+                    return utils.map(platform, function (details, version) {
+                        return {name: details.id, version: version};
+                    })[0];
+                })[0];
+
+        _current = db.retrieveObject(constants.PLATFORM.SAVED_KEY);
+
+        if (_current) {
+            _checkForDeprecatedPlatforms(firstAvailablePlatform);
+        } else {
+            _current = firstAvailablePlatform;
+        }
+
+        _console.prefix = _getPlatform().name;
+    },
+
+    getList: function () {
+        var platformList = {};
+
+        utils.forEach(spec, function (platform, platformKey) {
+            utils.forEach(platform, function (version, versionKey) {
+                platformList[platformKey] = platformList[platformKey] || {};
+                platformList[platformKey][versionKey] = {
+                    "id": version.id,
+                    "name": version.name,
+                    "type": version.type
+                };
+            });
+        });
+
+        return platformList;
+    },
+
+    getPersistencePrefix: function (id) {
+        return _getPlatform().persistencePrefix + (id || app.getInfo().id) + "-";
+    },
+
+    current: function () {
+        return _getPlatform();
+    },
+
+    changeEnvironment: function (platform, deviceId, callback) {
+        var save = jWorkflow.order(function (prev, baton) {
+                baton.take();
+                db.saveObject(constants.PLATFORM.SAVED_KEY, platform, null, baton.pass);
+            }).andThen(function (prev, baton) {
+                baton.take();
+                db.save(constants.DEVICE.SAVED_KEY, deviceId, null, baton.pass);
+            }).andThen(function (prev, baton) {
+                //remove the persisted value for the layout
+                baton.take();
+                db.save(constants.ENCAPSULATOR.LAYOUT, null, null, baton.pass);
+            }).andThen(function () {
+                event.trigger("PlatformChangedEvent", [], true);
+                _console.prefix = null;
+                _console.log("Emulator :: loading platform " + platform.name);
+            });
+
+        save.start(callback);
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/resizer', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var db = require('ripple/db'),
+    exception = require('ripple/exception'),
+    utils = require('ripple/utils'),
+    resizer = require('ripple/resizer'),
+    devices = require('ripple/devices'),
+    constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    self;
+
+function _validateLayoutType(layoutType) {
+    return (layoutType === constants.ENCAPSULATOR.DISPLAY_LAYOUT.LANDSCAPE || layoutType === constants.ENCAPSULATOR.DISPLAY_LAYOUT.PORTRAIT);
+}
+
+function _getContainers() {
+    return {
+        device: {
+            div: document.getElementById(constants.COMMON.DEVICE_CONTAINER),
+            containerClass: document.getElementById(constants.COMMON.DEVICE_CONTAINER).getAttribute("class") || ""
+        },
+        viewport: {
+            div: document.getElementById(constants.COMMON.VIEWPORT_CONTAINER),
+            containerClass: document.getElementById(constants.COMMON.VIEWPORT_CONTAINER).getAttribute("class") || ""
+        },
+        "menu-button": {
+            div: document.getElementById(constants.COMMON.MENU_BUTTON),
+            containerClass: document.getElementById(constants.COMMON.MENU_BUTTON).getAttribute("class") || ""
+        },
+        "back-button": {
+            div: document.getElementById(constants.COMMON.BACK_BUTTON),
+            containerClass: document.getElementById(constants.COMMON.BACK_BUTTON).getAttribute("class") || ""
+        }
+    };
+}
+
+function _setContainers(containers, device, orientation) {
+    var suffix = {
+            portrait:  "-wrapper" + (device.skin ? "-" + device.skin : ""),
+            landscape: "-wrapper-landscape" + (device.skin ? "-" + device.skin : "")
+        };
+
+    utils.forEach(containers, function (container, key) {
+        container.div.setAttribute("class", container.containerClass.replace(/\s.*$/, "") + " " + key + suffix[orientation]);
+    });
+}
+
+function _getDimensions(device, orientation) {
+    return {
+        deviceWidth: orientation === "portrait" ? device.screen.width : device.screen.height,
+        deviceHeight: orientation === "portrait" ? device.screen.height : device.screen.width,
+        paddingLeft: device.viewPort[orientation].paddingLeft,
+        paddingTop: device.viewPort[orientation].paddingTop,
+        viewPort: {
+            width: device.viewPort[orientation].width,
+            height: device.viewPort[orientation].height
+        }
+    };
+}
+
+function _formatSkin(containers, dimensions) {    
+    containers.device.div.style.width = (dimensions.deviceWidth + 4) + "px";
+    containers.device.div.style.height = (dimensions.deviceHeight + 4) + "px";
+
+    containers.viewport.div.style.width = dimensions.viewPort.width + "px";
+    containers.viewport.div.style.height = dimensions.viewPort.height + "px";
+    containers.viewport.div.style.padding = dimensions.paddingTop + "px " + (dimensions.deviceWidth - (dimensions.viewPort.width + dimensions.paddingLeft)) + "px " +
+        (dimensions.deviceHeight - (dimensions.viewPort.height + dimensions.paddingTop)) + "px " + dimensions.paddingLeft + "px";
+}
+
+self = module.exports = {
+    // TODO: redo/refactor this in general, seems bloated, also devices REQUIRE viewport schemas which they shouldnt
+    resize: function (device) {
+        var layout = db.retrieve(constants.ENCAPSULATOR.LAYOUT),
+            orientation = "portrait",
+            containers, dimensions;
+
+        if (layout && layout === constants.ENCAPSULATOR.DISPLAY_LAYOUT.LANDSCAPE && device.viewPort.landscape) {
+            orientation = "landscape";
+        }
+
+        containers = _getContainers();
+
+        _setContainers(containers, device, orientation);
+
+        dimensions = _getDimensions(device, orientation);
+
+        if (!device.skin) {
+            _formatSkin(containers, dimensions);
+        }
+
+        event.trigger("ScreenChangeDimensions", [dimensions.viewPort.width, dimensions.viewPort.height]);
+    },
+
+    changeLayoutType: function (layoutType) {
+        if (!_validateLayoutType(layoutType)) {
+            exception.raise(exception.types.LayoutType, "unknown layout type requested!");
+        }
+
+        db.save(constants.ENCAPSULATOR.LAYOUT, layoutType);
+
+        self.resize(devices.getCurrentDevice());
+    }
+};
+
+});
+require.define('ripple/ui/plugins/information', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    devices = require('ripple/devices'),
+    event = require('ripple/event'),
+    platform = require('ripple/platform'),
+    utils = require('ripple/utils'),
+    app = require('ripple/app');
+
+function _updateInformationView() {
+    var infoPane = document.getElementById(constants.COMMON.INFO_SECTION),
+        infoList = [],
+        device = devices.getCurrentDevice(),
+        tempString = "",
+        widgetInfo = app.getInfo();
+
+    //TODO: refactor this stuff to grab info from API, do this in a loop rather then hardcoded. Better DOM injection approach. This is legacy code
+
+    infoList.push('<section id=\"information-banner\" style=\"display:none\"><img id=\"information-banner-icon\" width=\"16px\" height=\"16px\"/> <span id=\"information-banner-count\"></span></section>');
+
+    if (widgetInfo.icon) {
+        infoList.push('<section style="position: absolute; left: 260px;"  class="information-widgeticon"><img class="ui-corner-all" width="64" src="' + utils.appLocation() + widgetInfo.icon + '" alt="widget icon"/></section>');
+    }
+    if (widgetInfo.name) {
+        infoList.push('<section class="information-widgetname">' + widgetInfo.name + '</section>');
+        //Update Title
+        document.title = "Web Simulator - " + widgetInfo.name;
+    }
+
+    infoList.push('<table class="tf_panel-table" style="border-spacing: 0px;">');
+
+    infoList.push("<tr><td><label class=\"ui-text-label\">Platform: </label></td><td>" + platform.current().name + "</td></tr>");
+   
+    if (widgetInfo.version) {
+        infoList.push('<tr><td><label class=\"ui-text-label\">Version:</label></td><td>' + widgetInfo.version + '</td></tr>');
+    }
+    infoList.push("<tr><td><label class=\"ui-text-label\">Device: </label></td><td>" + device.name + "</td></tr>");
+    infoList.push("<tr><td><label class=\"ui-text-label\">Manufacturer: </label></td><td>" + device.manufacturer + "</td></tr>");
+    infoList.push("<tr><td><label class=\"ui-text-label\">OS: </label></td><td>" + device.osName + " " + device.osVersion + "</td></tr>");
+    infoList.push("<tr><td><label class=\"ui-text-label\">Screen: </label></td><td>" + device.screen.width + "x" + device.screen.height + "</td></tr>");
+
+    if (device.screen.height !== device.viewPort.portrait.height) {
+        infoList.push("<tr><td><label class=\"ui-text-label\">Viewport: </label></td><td>" + device.viewPort.portrait.width + "x" + device.viewPort.portrait.height + "</td></tr>");
+    }
+
+    infoList.push("<tr><td><label class=\"ui-text-label\">Pixel Density: </label></td><td>" + device.ppi + " PPI</td></tr>");
+    infoList.push("<tr><td><label class=\"ui-text-label\">Browser(s): </label></td><td>" + device.browser.join(", ") + "</td></tr>");
+    infoList.push("<tr><td><label class=\"ui-text-label\" style=\"float:left; padding-top: 0px; \">User Agent: </label></td><td>" +
+                    device.userAgent + "</td></tr>");
+
+    infoList.push('</table>');
+
+    if (device.notes) {
+        utils.forEach(device.notes, function (note) {
+            tempString += "<li>" + note + "</li>";
+        });
+        infoList.push("<section><div style=\"clear:both;\"></div><label class=\"ui-text-label\">Notes: </label><ul>" + tempString + "</ul></section>");
+    }
+
+    infoPane.innerHTML = infoList.join("");
+}
+
+function _updateBanner(icon, count) {
+    var bannerSection = document.getElementById("information-banner"),
+        iconImg  = document.getElementById("information-banner-icon"),
+        countSpan = document.getElementById("information-banner-count");
+
+    if (icon && (count === undefined || count > 0)) {
+        count = count || "";
+        jQuery("#" + constants.COMMON.INFO_SECTION).show();
+        jQuery(bannerSection).fadeToggle(1000);
+        jQuery(bannerSection).fadeIn(1000);
+    }
+    else {
+        jQuery(bannerSection).fadeOut(1000);
+    }
+
+    iconImg.src = utils.appLocation() + icon;
+    if (icon.indexOf("http") === 0) {
+        iconImg.src = icon;
+    }
+
+    countSpan.innerHTML = count > 99 ? "99+" : count;
+}
+
+module.exports = {
+    panel: {
+        domId: "information-container",
+        collapsed: false,
+        pane: "left",
+        titleName: "System Summary",
+        display: true
+    },
+    initialize: function () {
+        event.on("BannerUpdated", function (icon, count) {
+            _updateBanner(icon, count);
+        });
+
+        event.on("PlatformChangedEvent", function () {
+            _updateInformationView();
+        });
+
+        event.on("WidgetInformationUpdated", function () {
+            _updateInformationView();
+        });
+
+        _updateInformationView();
+    }
+};
+
+});
+require.define('ripple/ui/plugins/panelCollapse', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// TODO: could use a bit of refactoring sugar
+var db = require('ripple/db'),
+    constants = require('ripple/constants'),
+    _LEFT_PANEL_COLLAPSE = ".left-panel-collapse",
+    _RIGHT_PANEL_COLLAPSE = ".right-panel-collapse",
+    _LEFT_PANEL = ".left",
+    _MIDDLE_PANEL = ".middle",
+    _RIGHT_PANEL = ".right",
+    _SAVE_KEY = "panel-collapsed",
+    _leftEngaged, _rightEngaged, _store;
+
+
+$(function () { 
+    $(window).resize(function () {
+        var windowHeight = $(window).height();
+        jQuery(".PanelCollapseBar").css("top", windowHeight - 56);
+        jQuery("#left_div").css("height", $(window).height() - 21);
+        if (_store["left"] === true) {
+            jQuery("#middle_div").css("width", $(window).width());
+        } else {
+            jQuery("#middle_div").css("width", $(window).width() - 344);
+        }
+    });
+});
+
+
+function _persist() {
+    db.saveObject(_SAVE_KEY, _store);
+}
+
+function _updateLayout() {
+    var node = document.querySelector("#device-container"),
+        leftPanelClosed = document.querySelector(_LEFT_PANEL).style.opacity === "0.1",
+        rightPanelClosed = document.querySelector(_RIGHT_PANEL).style.opacity === "0.1";
+
+    if (leftPanelClosed && rightPanelClosed) {
+        node.style.margin = "0 auto 0 auto";
+    } else if (rightPanelClosed) {
+        jQuery(node).animate({
+            "marginRight": "3%"
+        });
+    } else if (leftPanelClosed) {
+        jQuery(node).animate({
+            "marginLeft": "3%"
+        });
+    } else {
+        node.style.margin = "0 auto 0 auto";
+    }
+}
+
+
+function updateZoomingValues(value, origin) {
+    var scaleFactor = value / 100, scaleString;
+    scaleString = "scale(" + scaleFactor + ")";
+    jQuery('#device-container').css('-webkit-transform', scaleString);
+    if (origin === "center") {
+        jQuery('#device-container').css('-webkit-transform-origin', 'center top');
+    } else {
+        jQuery('#device-container').css('-webkit-transform-origin', 'left top');
+    }
+}
+
+
+function _process(collapseNode, panelNode, side, callback) {
+    var jNode = collapseNode.children("span"),
+        jPanelNode = jQuery(panelNode),
+        properties = {},
+        collapseProperties = {},
+        options = {
+            duration: 600,
+            complete: callback
+        },
+        oldIcon, newIcon,
+        zoomingValue =  db.retrieve(constants.ENCAPSULATOR.ZOOMING);
+
+    if (_store[side] === true) {
+        _store[side] = false;
+        
+        if (side === "left") {
+            jQuery('#left_div').show("fast");
+            collapseNode.removeClass("PanelCollapseBarCollapsed");
+            collapseNode.addClass("PanelCollapseBar");
+            collapseNode.children().remove();
+            collapseNode.append('<img src="images/sideCollapseIconLeftSide.png" style="margin-left:330px; margin-top: 6px;"/>');
+            collapseNode.css("top", $(window).height() - 56);
+            collapseNode.css("left", 0);
+            jQuery("#middle_div").css("width", $(window).width() - 344);
+            jQuery("#middle_div").css("left", 347);
+            jQuery("#device-container").css("margin-left", "21px");
+            updateZoomingValues(zoomingValue, "left");
+        }
+        
+        oldIcon = (side === "left" ? "ui-icon-arrowthick-1-e" : "ui-icon-arrowthick-1-w");
+        newIcon = (side === "left" ? "ui-icon-arrowthick-1-w" : "ui-icon-arrowthick-1-e");
+
+        properties[side] = "0px";
+        collapseProperties[side] = "345px";
+        properties.opacity = "1";
+    } else {
+        _store[side] = true;
+        
+        if (side === "left") {
+            collapseNode.removeClass("PanelCollapseBar");
+            collapseNode.addClass("PanelCollapseBarCollapsed");
+            collapseNode.children().remove();
+            collapseNode.append('<img src="images/sideCollapseIconRightSide.png" style="position: absolute; margin-left:5px; margin-top:48%;"/>');
+            collapseNode.css("top", 10);
+            collapseNode.css("left", 0);
+            collapseNode.css("margin-left", 0);
+            jQuery('#left_div').hide("slow");
+            jQuery("#middle_div").css("width", $(window).width() - 20);
+            jQuery("#middle_div").css("left", 20);
+            jQuery("#device-container").css("margin-left", "21px");
+            updateZoomingValues(zoomingValue, "left");
+        }
+        
+        oldIcon = (side === "left" ? "ui-icon-arrowthick-1-w" : "ui-icon-arrowthick-1-e");
+        newIcon = (side === "left" ? "ui-icon-arrowthick-1-e" : "ui-icon-arrowthick-1-w");
+
+        properties[side] = "-340px";
+        collapseProperties[side] = "5px";
+        properties.opacity = "0.1";
+    }
+
+    jNode.removeClass(oldIcon).addClass(newIcon);
+
+    jPanelNode.animate(properties, options);
+    //collapseNode.animate(collapseProperties, 600);
+
+    _persist();
+}
+
+module.exports = {
+    initialize: function () {
+        var rightCollapseNode = jQuery(_RIGHT_PANEL_COLLAPSE),
+            leftCollapseNode = jQuery(_LEFT_PANEL_COLLAPSE),
+            zoomingValue =  db.retrieve(constants.ENCAPSULATOR.ZOOMING);
+            //deviceNode = jQuery(_MIDDLE_PANEL);
+           
+        _store = db.retrieveObject(_SAVE_KEY) || {
+            left: false,
+            right: false
+        };
+
+        jQuery("#left_div").css("height", $(window).height() - 21);
+        jQuery("#middle_div").css("width", $(window).width() - 344);
+        
+        //deviceNode.draggable({ cursor: 'move'});
+    
+        if (_store.left === true) {
+            jQuery(_LEFT_PANEL).css({
+                left: "-340px",
+                opacity: "0.1"
+            });
+            
+            leftCollapseNode.removeClass("PanelCollapseBar");
+            leftCollapseNode.addClass("PanelCollapseBarCollapsed");
+            leftCollapseNode.children().remove();
+            leftCollapseNode.append('<img src="images/sideCollapseIconRightSide.png" style="position: absolute; margin-left:5px; margin-top:48%;"/>');
+            leftCollapseNode.css("top", 10);
+            leftCollapseNode.css("left", 0);
+            leftCollapseNode.css("margin-left", 0);
+            jQuery('#left_div').hide();
+            jQuery("#middle_div").css("width", $(window).width() - 20);
+            jQuery("#middle_div").css("left", 20);
+            jQuery("#device-container").css("margin-left", "21px");
+            updateZoomingValues(zoomingValue, "left");
+        } else {
+            jQuery('#left_div').show("fast");
+            leftCollapseNode.removeClass("PanelCollapseBarCollapsed");
+            leftCollapseNode.addClass("PanelCollapseBar");
+            leftCollapseNode.children().remove();
+            leftCollapseNode.append('<img src="images/sideCollapseIconLeftSide.png" style="margin-left:330px; margin-top: 6px;"/>');
+            leftCollapseNode.css("top", $(window).height() - 56);
+            leftCollapseNode.css("left", 0);
+            jQuery("#device-container").css("margin-left", "21px");
+            updateZoomingValues(zoomingValue, "left");
+        }   
+
+        if (_store.right === true) {
+            jQuery(_RIGHT_PANEL).css({
+                right: "-340px",
+                opacity: "0.1"
+            });
+
+            rightCollapseNode.css({
+                right: "5px"
+            }).children("span").removeClass("ui-icon-arrowthick-1-e").addClass("ui-icon-arrowthick-1-w");
+        }
+
+        leftCollapseNode.bind("click", function () {
+            if (!_leftEngaged) {
+                _leftEngaged = true;
+                _process(leftCollapseNode, _LEFT_PANEL, "left", function () {
+                    _leftEngaged = false;
+                });
+            }
+        });
+
+        rightCollapseNode.bind("click", function () {
+            if (!_rightEngaged) {
+                _rightEngaged = true;
+                _process(rightCollapseNode, _RIGHT_PANEL, "right", function () {
+                    _rightEngaged = false;
+                });
+            }
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/geoView', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    geo = require('ripple/geo'),
+    db = require('ripple/db'),
+    event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    platform = require('ripple/platform'),
+    markers,
+    _gpsMapZoomLevel;
+
+function _updateGpsMap() {
+    var positionInfo = geo.getPositionInfo(),
+            mapContainer = document.getElementById(constants.GEO.OPTIONS.MAP_CONTAINER),
+            geoZoomValue = document.getElementById(constants.GEO.MAP_ZOOM_LEVEL_CONTAINER);
+
+    if (mapContainer && jQuery(mapContainer).is(':visible')) {
+        geo.map.setCenter(new OpenLayers.LonLat(positionInfo.longitude, positionInfo.latitude) // Center of the map
+            .transform(
+              new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
+              new OpenLayers.Projection("EPSG:900913") // to Spherical Mercator Projection
+            ),
+            _gpsMapZoomLevel,
+            true // don't trigger dragging events
+        );
+    }
+
+    if (geoZoomValue) {
+        geoZoomValue.innerText = _gpsMapZoomLevel;
+    }
+}
+
+function _updateGpsMapZoom(goUp) {
+    if (goUp && _gpsMapZoomLevel < constants.GEO.MAP_ZOOM_MAX) {
+        _gpsMapZoomLevel++;
+    }
+    else if (!goUp && _gpsMapZoomLevel > constants.GEO.MAP_ZOOM_MIN) {
+        _gpsMapZoomLevel--;
+    }
+    document.getElementById(constants.GEO.MAP_ZOOM_LEVEL_CONTAINER).innerHTML = _gpsMapZoomLevel;
+
+    _updateGpsMap();
+
+    db.save(constants.GEO.MAP_ZOOM_KEY, _gpsMapZoomLevel);
+}
+
+function _getTextHeading(heading) {
+    if (heading >= 337.5 || (heading >= 0 && heading <= 22.5)) {
+        return 'N';
+    }
+
+    if (heading >= 22.5 && heading <= 67.5) {
+        return 'NE';
+    }
+
+    if (heading >= 67.5 && heading <= 112.5) {
+        return 'E';
+    }
+    if (heading >= 112.5 && heading <= 157.5) {
+        return 'SE';
+    }
+
+    if (heading >= 157.5 && heading <= 202.5) {
+        return 'S';
+    }
+
+    if (heading >= 202.5 && heading <= 247.5) {
+        return 'SW';
+    }
+
+    if (heading >= 247.5 && heading <= 292.5) {
+        return 'W';
+    }
+
+    if (heading >= 292.5 && heading <= 337.5) {
+        return 'NW';
+    }
+}
+
+module.exports = {
+    panel: {
+        domId: "gps-container",
+        collapsed: true,
+        pane: "left",
+        titleName: "Geolocation",
+        display: true
+    },
+
+    initialize: function () {
+        var GEO_OPTIONS = constants.GEO.OPTIONS,
+            positionInfo = geo.getPositionInfo(),
+            positionEvent = "PositionInfoUpdatedEvent",
+            latitude = document.getElementById(GEO_OPTIONS.LATITUDE),
+            longitude = document.getElementById(GEO_OPTIONS.LONGITUDE),
+            altitude = document.getElementById(GEO_OPTIONS.ALTITUDE),
+            accuracy = document.getElementById(GEO_OPTIONS.ACCURACY),
+            altitudeAccuracy = document.getElementById(GEO_OPTIONS.ALTITUDE_ACCURACY),
+            heading = document.getElementById(GEO_OPTIONS.HEADING),
+            speed = document.getElementById(GEO_OPTIONS.SPEED),
+            cellID = document.getElementById(GEO_OPTIONS.CELL_ID),
+            delay = document.getElementById(GEO_OPTIONS.DELAY),
+            delayLabel = document.getElementById(GEO_OPTIONS.DELAY_LABEL),
+            headingLabel = document.getElementById(GEO_OPTIONS.HEADING_LABEL),
+            headingMapLabel = document.getElementById(GEO_OPTIONS.HEADING_MAP_LABEL),
+            timeout = document.getElementById(GEO_OPTIONS.TIMEOUT),
+            mapContainer = document.getElementById(GEO_OPTIONS.MAP_CONTAINER),
+            map = null;
+
+
+        function updateGeo() {
+            if (parseFloat(latitude.value) > 90)
+                latitude.value = 90;
+            else if (parseFloat(latitude.value) < -90)
+                latitude.value = -90;
+            
+            if (parseFloat(longitude.value) > 180)
+                longitude.value = 180;
+            else if (parseFloat(longitude.value) < -180)
+                longitude.value = -180; 
+                
+            geo.updatePositionInfo({
+                latitude: parseFloat(latitude.value),
+                longitude: parseFloat(longitude.value),
+                altitude: parseInt(altitude.value, 10),
+                accuracy: parseInt(accuracy.value, 10),
+                altitudeAccuracy: parseInt(altitudeAccuracy.value, 10),
+                heading: heading.value ? parseFloat(heading.value) : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
+                speed: speed.value ? parseInt(speed.value, 10) : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
+                cellID: cellID.value,
+                timeStamp: new Date()
+            },
+            delay.value,
+            timeout.checked);
+        }
+
+        function updateHeadingValues() {
+            var headingDeg = parseFloat(heading.value),
+                headingText = _getTextHeading(parseFloat(heading.value));
+
+            headingLabel.innerText = headingText;
+            headingMapLabel.innerHTML = headingText + "</br>" + headingDeg + "&deg;";
+        }
+
+        function updateValsFromMap() {
+            var center = geo.map.getCenter().transform(
+                new OpenLayers.Projection("EPSG:900913"),
+                new OpenLayers.Projection("EPSG:4326"));
+            longitude.value = center.lon;
+            latitude.value = center.lat;
+            updateGeo();
+        }
+
+        function initializeValues() {
+            latitude.value =          positionInfo.latitude;
+            longitude.value =         positionInfo.longitude;
+            altitude.value =          positionInfo.altitude;
+            accuracy.value =          positionInfo.accuracy;
+            altitudeAccuracy.value =  positionInfo.altitudeAccuracy;
+            cellID.value =            positionInfo.cellID;
+            delay.value = document.getElementById(GEO_OPTIONS.DELAY_LABEL).innerText = geo.delay || 0;
+            if (geo.timeout) {
+                timeout.checked = true;
+            }
+            updateHeadingValues();
+        }
+
+        function initMap() {
+            var marker, clickHandler;
+            // override image location so we don't have to include image assets
+            OpenLayers.ImgPath = 'http://openlayers.org/api/img/';
+
+            // init map
+            geo.map = new OpenLayers.Map(mapContainer, { controls: [] });
+
+            // add controls and OSM map layer
+            geo.map.addLayer(new OpenLayers.Layer.OSM());
+            geo.map.addControl(new OpenLayers.Control.Navigation());
+
+            // override behaviour of click to pan and double click to zoom in
+            clickHandler = new OpenLayers.Handler.Click(
+                this,
+                {
+                    click: function (e) {
+                        var lonlat = geo.map.getLonLatFromViewPortPx(e.xy);
+                        geo.map.panTo(new OpenLayers.LonLat(lonlat.lon, lonlat.lat), _gpsMapZoomLevel);
+                    },
+
+                    dblclick: function (e) {
+                        _updateGpsMapZoom(true);
+                    }
+                },
+                {double: true}
+            );
+
+            // add click handler to map
+            clickHandler.setMap(geo.map);
+            clickHandler.activate();
+
+            // update long and lat when map is panned
+            geo.map.events.register("moveend", map, function (e) {
+                updateValsFromMap();
+            });
+
+            event.on("ApplicationState", function (obj) {
+                if (obj && obj[0].id === 'gps-container' && obj.hasClass('ui-box-open')) {
+                    _updateGpsMap();
+                }
+            });
+            _updateGpsMap();
+            markers = new OpenLayers.Layer.Markers("markers");
+            geo.map.addLayer(markers);
+            marker = new OpenLayers.Marker(geo.map.getCenter(),
+                    new OpenLayers.Icon("images/arrow.png", new OpenLayers.Size(22, 30), new OpenLayers.Pixel(-11, -15)));
+            markers.addMarker(marker);
+
+            geo.map.events.register("move", map, function (e) {
+                markers.clearMarkers();
+                marker = new OpenLayers.Marker(geo.map.getCenter(),
+                        new OpenLayers.Icon("images/arrow.png", new OpenLayers.Size(22, 30), new OpenLayers.Pixel(-11, -15)));
+                markers.addMarker(marker);
+            });
+
+        }
+
+        // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847 (double HACK!!!)
+        if (platform.current().id === 'phonegap' || platform.current().id === 'webworks' || platform.current().id === 'wac') {
+            // make the fields visible
+            jQuery("#geo-cellid-container").hide();
+            jQuery("#geo-heading-container").show();
+            jQuery("#geo-speed-container").show();
+        }
+        else {
+            jQuery("#geo-cellid-container").show();
+            jQuery("#geo-heading-container").hide();
+            jQuery("#geo-speed-container").hide();
+        }
+
+        _gpsMapZoomLevel = db.retrieve(constants.GEO.MAP_ZOOM_KEY) || 14;
+
+        jQuery("#geo-map-zoom-decrease").bind("click", function () {
+            _updateGpsMapZoom(false);
+        });
+
+        jQuery("#geo-map-zoom-increase").bind("click", function () {
+            _updateGpsMapZoom(true);
+        });
+
+        utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.LATITUDE), updateGeo);
+        utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.LONGITUDE), updateGeo);
+        utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.ALTITUDE), updateGeo);
+        utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.ACCURACY), updateGeo);
+        utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.ALTITUDE_ACCURACY), updateGeo);
+        utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.CELL_ID), updateGeo);
+        jQuery("#" + GEO_OPTIONS.DELAY).bind("change", function () {
+            updateGeo();
+            delayLabel.innerText = delay.value;
+        });
+        jQuery("#" + GEO_OPTIONS.TIMEOUT).bind("click", function () {
+            updateGeo();
+        });
+
+        // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847 (double HACK!!!)
+        if (platform.current().id === 'phonegap' || platform.current().id === 'webworks' || platform.current().id === 'wac') {
+            jQuery("#" + GEO_OPTIONS.HEADING).bind("change", function () {
+                updateGeo();
+                updateHeadingValues();
+            });
+
+            utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.SPEED), updateGeo);
+            heading.value =       positionInfo.heading;
+            speed.value =         positionInfo.speed;
+        }
+
+        initMap();
+        if (navigator.onLine === false) {
+            jQuery("#disable_geo_panel").show();
+        }
+        jQuery(window).bind("online", function () {
+            jQuery("#disable_geo_panel").hide();
+            console.log("ONLINE");
+        });
+        jQuery(window).bind("offline", function () {
+            jQuery("#disable_geo_panel").show();
+            console.log("OFFLINE");
+        });
+
+        initializeValues();
+
+        event.on(positionEvent, function () {
+            _updateGpsMap();
+        });
+
+        event.trigger(positionEvent, [{
+                latitude: latitude.value,
+                longitude: longitude.value,
+                altitude: altitude.value,
+                accuracy: accuracy.value,
+                altitudeAccuracy: altitudeAccuracy.value,
+                heading: heading ? heading.value : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
+                speed: speed ? speed.value : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
+                cellID: cellID.value,
+                timeStamp: new Date()
+            }]);
+    }
+};
+
+});
+require.define('ripple/ui/plugins/battery', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var event = require('ripple/event'),
+    db = require('ripple/db'),
+    constants = require('ripple/constants');
+
+module.exports = {
+    panel: {
+        domId: "battery-container",
+        collapsed: true,
+        pane: "left",
+        titleName: "Battery",
+        display: true
+    },
+    initialize: function () {
+        var time     = document.getElementById(constants.BATTERY.TIME),
+            volume   = document.getElementById(constants.BATTERY.VOLUME),
+            charging = document.getElementById(constants.BATTERY.CHARGING),
+            comment  = document.getElementById("error-comment"),
+            INTERVAL = 1000,
+            isValid  = false,
+            interval,
+            _volume;
+
+
+        function updateBatteryVolumeValues() {
+            var volumeStr = _volume, batteryVolume, timeValue;
+
+            batteryVolume = Math.round(_volume * 100) / 100 + "%";
+            timeValue = volumeStr * time.value / 100.0;
+            timeValue = Math.round(timeValue * 100) / 100;
+            document.getElementById("battery-volume-label").innerHTML = batteryVolume;
+            document.getElementById("battery-remaining-power").innerHTML = timeValue;
+        }
+
+        function initializeValues() {
+            var timeValue     =  db.retrieve(constants.BATTERY.TIME) || 600,
+                volumeValue   =  db.retrieve(constants.BATTERY.VOLUME) || 100,
+                chargingValue =  db.retrieve(constants.BATTERY.CHARGING);
+
+            chargingValue = (chargingValue === "true");
+            _volume       =   volumeValue * 1.00;
+            document.getElementById(constants.BATTERY.TIME).value       = timeValue;
+            document.getElementById(constants.BATTERY.VOLUME).value     = volumeValue;
+            document.getElementById(constants.BATTERY.CHARGING).checked = chargingValue;
+
+            updateBatteryVolumeValues();
+            chargingVolume();
+            interval = setInterval(chargingVolume, INTERVAL);
+        }
+        function updateBattery() {
+            var timeValue     =  db.retrieve(constants.BATTERY.TIME) || 600,
+                volumeValue   =  db.retrieve(constants.BATTERY.VOLUME) || 100;
+
+            clearInterval(interval);
+            _volume       =   volumeValue * 1.00;
+            document.getElementById(constants.BATTERY.TIME).value       = timeValue;
+            document.getElementById(constants.BATTERY.VOLUME).value     = volumeValue;
+            updateBatteryVolumeValues();
+            interval = setInterval(chargingVolume, INTERVAL);
+        }
+        document.getElementById(constants.BATTERY.TIME)
+            .addEventListener("change", function () {
+                if (time.value > 0 && time.value <= 600) {
+                    comment.style.display = "none";
+                    time.style.color = "black";
+                    db.save(constants.BATTERY.TIME, time.value);
+                    updateBattery();
+                } else {
+                       comment.style.display = "inline";
+                    time.style.color = "red";
+                    updateBattery();
+                }
+            }, false);
+
+        document.getElementById(constants.BATTERY.VOLUME)
+            .addEventListener("change", function () {
+                _volume = volume.value * 1.00;
+                updateBatteryVolumeValues();
+                db.save(constants.BATTERY.VOLUME, volume.value);
+                clearInterval(interval);
+                interval = setInterval(chargingVolume, INTERVAL);
+            }, false);
+
+        document.getElementById(constants.BATTERY.CHARGING)
+            .addEventListener("change", function () {
+                db.save(constants.BATTERY.CHARGING, charging.checked);
+                clearInterval(interval);
+                interval = setInterval(chargingVolume, INTERVAL);
+            }, false);
+
+        function chargingVolume() {
+            var step, status, level, type, batteryLifeTime, batteryPercent, chargingStatus, chargingTime, dischargingTime;
+
+            batteryLifeTime = 60.0 * time.value;
+            batteryPercent = _volume * 1.0;
+
+            if (charging.checked) {
+                step = 100;
+                chargingStatus = true;
+                // charging is 10 times faster than discharging
+                chargingTime = (batteryLifeTime * (100.0 - batteryPercent)) / 100.0 / 10.0;
+                dischargingTime = Infinity;
+                type = "chargingchange";
+
+                if (batteryPercent + 100 / batteryLifeTime > 99.9999) {
+                    clearInterval(interval);
+                }
+            } else {
+                step = -100;
+                chargingStatus = false;
+                chargingTime = Infinity;
+                dischargingTime = batteryLifeTime * batteryPercent / 100.0;
+                type = "dischargingtimechange";
+
+                if (batteryPercent - 100 / batteryLifeTime < 0.0001) {
+                    clearInterval(interval);
+                }
+            }
+            level = (_volume  + step /(60.0 *  time.value)) / 100.0;
+            if (level < 0.0001) {
+                level = 0;
+            } else if (level > 0.9999) {
+                level = 1.0;
+            }
+
+            status = {
+                charging: chargingStatus,
+                chargingTime: chargingTime,
+                dischargingTime: dischargingTime,
+                level: level,
+                type: type
+            };
+
+            event.trigger("BatteryEvent", [status]);
+            _volume = level * 100.0;
+            document.getElementById(constants.BATTERY.VOLUME).value = Math.round(level * 100.00);
+            updateBatteryVolumeValues();
+        }
+
+        initializeValues();
+    }
+};
+
+});
+require.define('ripple/ui/plugins/fileSystem', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    constants = require('ripple/constants'),
+    fileSystem = require('ripple/fileSystem'),
+    fileSystemPaths = fileSystem.getFileSystemPaths();
+
+module.exports = {
+    panel: {
+        domId: "filsystem-container",
+        collapsed: true,
+        pane: "left"
+    },
+    initialize: function () {
+        var fileSystemPaths = fileSystem.getFileSystemPaths();
+
+        utils.forEach(fileSystemPaths, function (value, key) {
+            utils.bindAutoSaveEvent(jQuery(constants.FILESYSTEM.INPUT_PREFIX_ID + key).val(value.uri), function () {
+                value.uri = jQuery(constants.FILESYSTEM.INPUT_PREFIX_ID + key).val();
+                fileSystem.updateFileSystemPaths(fileSystemPaths);
+            });
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/firstRunCheck', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    constants = require('ripple/constants'),
+    _platform = require('ripple/platform'),
+    db = require('ripple/db');
+
+function _handleFirstRunResponse(platform, version) {
+    var device = jQuery("#device-select").val(),
+        api = {
+            name: platform.id,
+            version: version
+        };
+
+
+    _platform.changeEnvironment(api, device, function () {
+        location.reload();
+    });
+}
+
+function _addPlatformButton(platform, version) {
+    var section = jQuery(".platform-select-buttons"),
+        buttonID = "platform-" + platform.id,
+        button = utils.createElement("button", {
+            "id": buttonID,
+            "class": "ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
+        });
+
+    button.appendChild(utils.createElement("span", {
+        "class": "ui-button-text",
+        "innertext" : platform.name
+    }));
+
+    section.append(button);
+
+    document.getElementById(buttonID).addEventListener("click", function () {
+        _handleFirstRunResponse(platform, version);
+    });
+}
+
+function _initializeFirstRunCheck() {
+    var savedPlatform = db.retrieveObject(constants.PLATFORM.SAVED_KEY),
+        firstRunOverlayNode, firstRunOptionsNode,
+        width, p;
+
+    if (!savedPlatform) {
+        width = jQuery(document).width();
+        p = (width / 2) - 277;
+
+        firstRunOverlayNode = jQuery(".first-run-window").css({display: 'block'});
+        firstRunOptionsNode = jQuery(".platform-select-dialog").css({display: 'block', left: p + "px"});
+
+        utils.forEach(_platform.getList(), function (platform) {
+            utils.forEach(platform, function (details, version) {
+                _addPlatformButton(details, version);
+            });
+        });
+    }
+}
+
+module.exports = {
+    initialize: function () {
+        if (utils.map(_platform.getList(), function (platform) {
+            return platform;
+        }).length > 1) {
+            _initializeFirstRunCheck();
+        }
+    }
+};
+
+});
+require.define('ripple/ui/plugins/deviceSettings', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    constants = require('ripple/constants'),
+    deviceSettings = require('ripple/deviceSettings'),
+    utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    platform = require('ripple/platform'),
+    _CONST = {
+        "CONTENT_CONTAINER_ID": "devicesettings-content-container",
+        "UKNOWN_CONTROL_MESSAGE": "Unknown device control type"
+    },
+    _contentContainer,
+    _CONTAINER_ID = _CONST.CONTENT_CONTAINER_ID;
+
+function _retrieveDeviceInfo(key) {
+    var deviceInfo = require('ripple/devices').getCurrentDevice();
+
+    switch (key) {
+    case "Device.model":
+        return deviceInfo.model;
+    case "Device.version":
+        return deviceInfo.firmware;
+    case "Device.vendor":
+        return deviceInfo.manufacturer;
+    case "Display.resolutionHeight":
+        return deviceInfo.screen.height;
+    case "Display.resolutionWidth":
+        return deviceInfo.screen.width;
+    case "Display.pixelAspectRatio":
+        return (deviceInfo.screen.width / deviceInfo.screen.height).toFixed(2);
+
+    case "Display.physicalWidth":
+        return (deviceInfo.screen.width/deviceInfo.ppi).toFixed(2);
+    case "Display.physicalHeight":
+        return (deviceInfo.screen.height/deviceInfo.ppi).toFixed(2);
+    case "Display.dpiY":
+    case "Display.dotsPerInchHeight":
+        return deviceInfo.ppi;
+    case "Display.dpiX":
+    case "Display.dotsPerInchWidth":
+        return deviceInfo.ppi;
+    case "OperatingSystem.version":
+        return deviceInfo.osVersion;
+    case "OperatingSystem.name":
+        return deviceInfo.osName;
+    case "OperatingSystem.vendor":
+        return deviceInfo.manufacturer;
+    default:
+        return deviceSettings.retrieve(key);
+    }
+}
+
+function _retrieveSettingName(type) {
+    var deviceInfo = require('ripple/devices').getCurrentDevice();
+    
+    switch (type) {
+    case "CellularHardware":
+        return "Cellular Hardware";
+    case "CellularNetwork":
+        return "Cellular Network";
+    case "MemoryUnit":
+        return "Memory Unit";
+    case "OperatingSystem":
+        return "Operating System";
+    case "WebRuntime":
+        return "Web Runtime";
+    case "WiFiHardware":
+        return "WiFi Hardware";
+    case "WiFiNetwork":
+        return "WiFi Network";
+    default:
+        return type;
+    }
+}
+
+function _appendSettingNode(labelNode, inputNode, label) {
+    var frag = document.createDocumentFragment(),
+        rowNode = frag.appendChild(utils.createElement("tr")),
+        tempTdNode;
+
+    rowNode.appendChild(utils.createElement("td"))
+           .appendChild(labelNode);
+
+    tempTdNode = rowNode.appendChild(utils.createElement("td"));
+
+    if (label) {
+        tempTdNode.appendChild(label);
+    }
+
+    tempTdNode.appendChild(inputNode);
+
+    return frag;
+}
+
+function _buildDOMNode(setting, settingType, key) {
+    var settingsNode, tagName, jNode,
+        fullKey = settingType + "." + key,
+        savedSetting = _retrieveDeviceInfo(fullKey),
+        // TODO: move this into Utils (isSet method)
+        currentSetting = (savedSetting || savedSetting === false || savedSetting === "" || savedSetting === 0) ? savedSetting : setting.control.value,
+        domNode,
+        domNodeLabel = null;
+
+
+    switch (setting.control.type) {
+    case "text":
+    case "number":
+    case "range":
+    case "checkbox":
+        tagName = "input";
+        break;
+    case "textarea":
+        tagName = "textarea";
+        break;
+    case "select":
+        tagName = "select";
+        break;
+    case "label":
+        tagName = "label";
+        break;
+    default:
+        exception.raise(exception.types.Application, _CONST.UKNOWN_CONTROL_MESSAGE);
+    }
+
+    settingsNode = utils.createElement(tagName, setting.control.type === "select" ? null : setting.control);
+    settingsNode.setAttribute("id", "device-settings-" + settingType + "-" + key);
+
+    // TODO: this should really be part of utils.createControl? add element of type "range" with label?
+    if (setting.control.type === "range") {
+        domNodeLabel = utils.createElement("label", {
+            "class": constants.UI.LEFT_RANGE_LABEL_CLASS
+        });
+    }
+
+    domNode = _appendSettingNode(utils.createElement("span", {"innerText": setting.name, "class": constants.UI.TEXT_LABEL_CLASS}), settingsNode, domNodeLabel);
+
+    jNode = jQuery(settingsNode);
+    if (tagName !== "label") {
+        jNode.addClass(constants.UI.JQUERY_UI_INPUT_CLASSES);
+    }
+
+    switch (setting.control.type) {
+    case "checkbox":
+        jNode.bind("click", function () {
+            var checked = this.checked ? true : false;
+            deviceSettings.persist(fullKey, checked);
+            if (typeof setting.callback === "function") {
+                setting.callback(checked);
+            }
+        });
+
+        if (currentSetting === true) {
+            jNode.attr("checked", "checked");
+        }
+
+        break;
+
+    case "text":
+    case "textarea":
+    case "number":
+        jNode.val(currentSetting);
+        utils.bindAutoSaveEvent(jNode, function () {
+            deviceSettings.persist(fullKey, jNode.val());
+            if (typeof setting.callback === "function") {
+                setting.callback(jNode.val());
+            }
+        });
+        break;
+    
+    case "label":
+        jNode.text(currentSetting);
+        break;
+
+    case "select":
+    case "range":
+        if (setting.control.type === "select") {
+            utils.forEach(setting.options,  function (value, option) {
+                jNode.append(utils.createElement("option", {
+                    "value": option,
+                    "innerText": value
+                }));
+            });
+        }
+        else {
+            if (domNodeLabel) {
+                domNodeLabel.innerText = currentSetting;
+            }
+        }
+
+        jNode.val(currentSetting)
+             .bind("change", function () {
+                if (setting.control.type === "range" && domNodeLabel) {
+                    domNodeLabel.innerText = jQuery(this).val();
+                }
+//                    deviceSettings.register(fullKey, jQuery(this).val());
+                deviceSettings.persist(fullKey, jQuery(this).val());
+
+                if (typeof setting.callback === "function") {
+                    setting.callback(jQuery(this).val());
+                }
+            }
+        );
+    }
+
+    // TODO: Brent, do in DeviceSettings on load instead?
+    if (currentSetting !== setting.control.value) {
+        deviceSettings.register(fullKey, currentSetting);
+    }
+
+    return domNode;
+}
+
+// goes through current platforms device settings
+// adds nodes to panel and binds respective events
+// talks to DeviceSettings for persistence
+module.exports = {
+    panel: {
+        domId: "devicesettings-panel-container",
+        collapsed: true,
+        pane: "right",
+        titleName: "Device & Network Settings",
+        display: true
+    },
+    initialize: function () {
+        var settings;
+
+        _contentContainer = document.getElementById(_CONTAINER_ID);
+
+        settings = platform.current().device;
+
+        utils.forEach(settings, function (settingSection, settingType) {
+
+            var currentTableNode, settingNameNode, settingName = _retrieveSettingName(settingType);
+
+                       settingNameNode = utils.createElement("h3", { "innerText": settingName });
+                       settingNameNode.setAttribute("class", "PanelSectionTitle");
+            _contentContainer.appendChild(settingNameNode);
+
+            currentTableNode = utils.createElement("table", {
+                "class": constants.UI.PANEL_TABLE_CLASS
+            });
+                       currentTableNode.setAttribute("class", "tf_panel-table2");
+            _contentContainer.appendChild(currentTableNode);
+
+            utils.forEach(settingSection, function (setting, key) {
+
+                currentTableNode.appendChild(_buildDOMNode(setting, settingType, key));
+
+            });
+        });
+        event.on("CpuLoadChanged", function (value) {
+            document.getElementById("device-settings-Cpu-load").value = value;
+        });
+        event.on("DisplayBrightnessChanged", function (value) {
+            document.getElementById("device-settings-Display-brightness").value = value;
+        });
+        event.on("CpuLoadChangedByPower", function (value) {
+            document.getElementById("device-settings-Cpu-load").value = value;
+        });
+        event.on("DisplayBrightnessChangedByPower", function (value) {
+            document.getElementById("device-settings-Display-brightness").value = value;
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/goodVibrations', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants');
+
+module.exports = {
+    vibrateDevice: function (milliseconds) {
+        var node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
+            x, times;
+
+        times = Math.floor(milliseconds / 100);
+
+        for (x = 1; x <= times; x++) {
+            node.animate({ left: -10 }, 5)
+            .animate({ left: 0 }, 1)
+            .animate({ left: 10 }, 5)
+            .animate({ left: 0 }, 1);
+
+            node.animate({ top: -10 }, 5)
+            .animate({ top: 0 }, 1)
+            .animate({ top: 10 }, 5)
+            .animate({ top: 0 }, 1);
+        }
+    },
+    shakeDevice: function (times) {
+        var node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
+            x;
+
+        for (x = 1; x <= times; x++) {
+            node.animate({ left: -25 }, 50)
+            .animate({ left: 0 }, 30)
+            .animate({ left: 25 }, 50)
+            .animate({ left: 0 }, 30);
+        }
+    }
+};
+
+});
+require.define('ripple/ui/plugins/storage', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    platform = require('ripple/platform'),
+    utils = require('ripple/utils'),
+    app = require('ripple/app'),
+    db = require('ripple/db');
+
+function _updatePreferencesView() {
+    var node = document.getElementById(constants.COMMON.STORAGE_TABLE_BODY_CLASS),
+        countTitle = document.getElementById(constants.COMMON.STORAGE_COUNT_CONTAINER_ID);
+
+    // TODO: convert to appendChild
+    if (node) {
+        db.retrieveAll(platform.getPersistencePrefix(), function (results) {
+            var str = "",
+                counter = 0;
+
+            utils.forEach(results, function (value, key) {
+                // TODO: based of current platform
+                if (app.isPreferenceReadOnly(key)) {
+                    str += '<tr class="ui-text-highlight">';
+                } else {
+                    str += '<tr>';
+                }
+                str += '<td>' + key + '</td><td>' + value + "</td></tr>";
+                counter ++;
+            });
+
+            node.innerHTML = str;
+            countTitle.innerHTML = counter.toString();
+
+            if (counter === 0) {
+                jQuery("#" + constants.COMMON.STORAGE_CLEAR_BUTTON_ID).addClass(constants.CSS_PREFIX.IRRELEVANT);
+            }
+            else {
+                jQuery("#" + constants.COMMON.STORAGE_CLEAR_BUTTON_ID).removeClass(constants.CSS_PREFIX.IRRELEVANT);
+            }
+        });
+    }
+}
+
+module.exports = {
+    panel: {
+        domId: "preferences",
+        collapsed: true,
+        pane: "left"
+    },
+    initialize: function () {
+        jQuery("#preferences-clear-button").bind("click", function () {
+            db.removeAll(platform.getPersistencePrefix());
+        });
+
+        event.on("StorageUpdatedEvent", function () {
+            _updatePreferencesView();
+        });
+
+        _updatePreferencesView();
+    }
+};
+
+});
+require.define('ripple/ui/plugins/devices', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    db = require('ripple/db');
+
+function _getTextZooming(zooming) {
+    return zooming + '%';
+}
+
+module.exports = {
+    panel: {
+        domId: "devices-container",
+        collapsed: true,
+        pane: "left",
+        titleName: "Resolution & Orientation",
+        display: true
+    },
+
+    initialize: function () {
+        var zooming = document.getElementById(constants.ENCAPSULATOR.ZOOMING);
+
+        function updateZoomingValues() {
+            var zoomingText, scaleFactor, scaleString;
+            
+            zoomingText = _getTextZooming(zooming.value);
+            jQuery('#screen-zooming-label').html(zoomingText);
+
+            // Zooming device skin
+            scaleFactor = zooming.value / 100;
+            scaleString = "scale(" + scaleFactor + ")";
+            jQuery('#device-container').css('-webkit-transform', scaleString);
+            jQuery('#device-container').css('-webkit-transform-origin', 'left top');
+        }
+
+        function initializeValues() {
+            var zoomingValue =  db.retrieve(constants.ENCAPSULATOR.ZOOMING);
+
+            if (!zoomingValue) {
+                zoomingValue = 100;
+            }
+            jQuery("#" + constants.ENCAPSULATOR.ZOOMING).val(zoomingValue);
+            updateZoomingValues();
+        }
+
+        jQuery("#" + constants.ENCAPSULATOR.ZOOMING).bind("change", function () {
+            updateZoomingValues();
+            db.save(constants.ENCAPSULATOR.ZOOMING, zooming.value);
+        });
+
+        initializeValues();
+    }
+};
+
+
+});
+require.define('ripple/ui/plugins/options', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var about = require('ripple/ui/plugins/about-dialog'),
+    settings = require('ripple/ui/plugins/settings-dialog'),
+    tooltip = require('ripple/ui/plugins/tooltip'),
+    hide,
+    show;
+
+show = function () {
+    if (settings.value("remoteInspector")) {
+        $("#options-menu-build-warning").show();
+        tooltip.create("#options-menu-build-warning", "Remote Web Inspector should be disabled when packaging for App World release");
+    }
+    else {
+        $("#options-menu-build-warning").hide();
+    }
+
+    $("#options-window").show();
+    $("#options-menu").show();
+};
+
+hide = function () {
+    $("#options-window").hide();
+    $("#options-menu").effect("fade", {}, 300);
+};
+
+module.exports = {
+    initialize: function () {
+        $("#options-menu").menu().hide();
+        $("#options-menu").bind("click", function (event) {
+            var target = $("#" + event.target.parentElement.id),
+                action;
+
+            if (target.hasClass("not-ready")) {
+                return;
+            }
+
+            switch (target.attr("id")) {
+            case "options-menu-build":
+            case "options-menu-launch":
+            case "options-menu-sign":
+                action = target.attr("id").split("-")[2];
+                if (!settings.can(action)) {
+                    settings.show(action);
+                }
+                else {
+                    settings.perform(action);
+                }
+                break;
+            case "options-menu-about":
+                about.show();
+                break;
+            case "options-menu-settings":
+                settings.show();
+                break;
+            default:
+                break;
+            }
+            hide();
+        });
+
+        $("#options-window").click(hide);
+        
+        $("#options-button-about").bind("click", function (event) {
+            about.show();
+        });
+        
+        hide();
+    }
+};
+
+});
+require.define('ripple/ui/plugins/audioPlayer', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    constants = require('ripple/constants'),
+    audioObj = document.getElementById("multimedia-audio"),
+    audioProgress = document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PROGRESS_ID);
+
+module.exports = {
+    initialize: function () {
+        var audioObj = document.getElementById("multimedia-audio"),
+            audioProgress = document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PROGRESS_ID);
+
+        if (audioObj) {
+            event.on("MultimediaVolumeChanged", function (volume) {
+                audioObj.volume = parseFloat(volume / 10);
+            });
+
+            audioObj.addEventListener("timeupdate", function () {
+                var s = parseInt(audioObj.currentTime % 60, 10),
+                    m = parseInt((audioObj.currentTime / 60) % 60, 10);
+
+                audioProgress.innerText = ((m > 9) ? m  : "0" + m) + ':' + ((s > 9) ? s  : "0" + s);
+            }, false);
+
+            event.on("MultimediaAudioStateChanged", function (state) {
+                document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_STATE_FIELD_ID).innerText = state;
+                document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_FILE_FIELD_ID).innerText = audioObj.getAttribute("src");
+            });
+        }
+    }
+};
+
+});
+require.define('ripple/ui/plugins/power', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('ripple/db'),
+    event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    constants = require('ripple/constants'),
+    deviceSettings = require('ripple/deviceSettings'),
+    power = require('ripple/platform/tizen/1.0/power');
+module.exports = {
+    panel: {
+        domId: "power-container",
+        collapsed: true,
+        pane: "left",
+        titleName: "Power",
+        display: true
+    },
+
+    initialize: function () {
+        var _RULES          =  constants.POWER_RULES,
+            _PORWER_RULES_KEY = "tizen1-db-power-role",
+            _CPU_STATE      = constants.POWER_RESOURCE.CPU.STATE,
+            _DISPLAY_STATE  = constants.POWER_RESOURCE.DISPLAY.STATE,
+            cpuObj           = document.getElementById("cpu-state"),
+            displayObj       = document.getElementById("display-state"),
+            loadLabel        = document.getElementById("cpu-load-label"),
+            brightnessLabel  = document.getElementById("diplay-brightness-label"),
+            load, brightness, stateObj;
+
+        function initPowerState() {
+            var obj, dbRules;
+            load = deviceSettings.retrieve("Cpu.load");
+            brightness = deviceSettings.retrieve("Display.brightness");
+            brightness = Number(brightness);
+            loadLabel.innerHTML = "CPU : (load = " + load + ")";
+            brightnessLabel.innerHTML = "Display : (brightness = " + brightness + ")";
+            //Init CPU state.
+            if (load <= _CPU_STATE.LOW.MAX) {
+                cpuObj.options[0].selected = true;//LOW
+            } else {
+                cpuObj.options[1].selected = true;
+            }
+            //Init DISPLAY state.
+            if (brightness ===  _DISPLAY_STATE.OFF.MAX) {
+                displayObj.options[0].selected = true;
+            } else if (brightness <= _DISPLAY_STATE.DIM.MAX) {
+                displayObj.options[1].selected = true;
+            } else if (brightness <= _DISPLAY_STATE.NORMAL.MAX) {
+                displayObj.options[2].selected = true;
+            } else {
+                displayObj.options[3].selected = true;
+            }
+            //Init rules
+            dbRules = db.retrieveObject(_PORWER_RULES_KEY);
+            _RULES =  dbRules && _RULES ? dbRules : _RULES;
+            for (obj in _RULES) {
+                stateObj = document.getElementById(obj.toLowerCase() + "-role");
+                if (_RULES[obj]) {//Allow : true
+                    stateObj.options[0].selected = true;
+                } else {//Deny : false
+                    stateObj.options[1].selected = true;
+                }
+            }
+        }
+        event.on("initPowerDB", function (rules) { //Update rule selects
+            var obj;
+            _RULES = rules;
+            for (obj in rules) {
+                stateObj = document.getElementById(obj.toLowerCase() + "-role");
+                if (rules[obj]) {//Allow : true
+                    stateObj.options[0].selected = true;
+                } else {//Deny : false
+                    stateObj.options[1].selected = true;
+                }
+            }
+        });
+        event.on("CpuLoadChanged", initPowerState);
+        event.on("DisplayBrightnessChanged", initPowerState);
+        event.on("CpuLoadChangedByPower", initPowerState);
+        event.on("DisplayBrightnessChangedByPower", initPowerState);
+        cpuObj.addEventListener("change", function () {
+            var state = cpuObj.value, value;
+            value = _CPU_STATE[state].VALUE;
+            deviceSettings.persist("Cpu.load", value);
+            event.trigger("CpuLoadChanged", [value]);
+        });
+        displayObj.addEventListener("change", function () {
+            var state = displayObj.value, value;
+            value = _DISPLAY_STATE[state].VALUE;
+            deviceSettings.persist("Display.brightness", value);
+            event.trigger("DisplayBrightnessChanged", [value]);
+        });
+        document.getElementById("high-role").addEventListener("change", function () {
+            var value = this.value;
+            value = (value === '1' ? true : false);
+            event.trigger("updatePowerRules", [{"state": 'HIGH', "value": value}]);
+        });
+        
+        document.getElementById("low-role").addEventListener("change", function () {
+            var value = this.value;
+            value = (value === '1' ? true : false);
+            event.trigger("updatePowerRules", [{"state": 'LOW', "value": value}]);
+        });
+        document.getElementById("off-role").addEventListener("change", function () {
+            var value = this.value;
+            value = (value === '1' ? true : false);
+            event.trigger("updatePowerRules", [{"state": 'OFF', "value": value}]);
+        });
+        document.getElementById("dim-role").addEventListener("change", function () {
+            var value = this.value;
+            value = (value === '1' ? true : false);
+            event.trigger("updatePowerRules", [{"state": 'DIM', "value": value}]);
+        });
+        document.getElementById("normal-role").addEventListener("change", function () {
+            var value = this.value;
+            value = (value === '1' ? true : false);
+            event.trigger("updatePowerRules", [{"state": 'NORMAL', "value": value}]);
+        });
+        document.getElementById("bright-role").addEventListener("change", function () {
+            var value = this.value;
+            value = (value === '1' ? true : false);
+            event.trigger("updatePowerRules", [{"state": 'BRIGHT', "value": value}]);
+        });
+        initPowerState();
+    }
+};
+
+});
+require.define('ripple/ui/plugins/accelerometer', function (require, module, exports) {
+/*
+ * Copyright (c) 2010 Epic Train Hack
+ * Copyright (c) 2011 Research In Motion Limited
+ * Contributors: Wolfram Kriesing, Dan Silivestru, Brent Lintner
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+var ui = require('ripple/ui'),
+    goodVibrations = require('ripple/ui/plugins/goodVibrations'),
+    accelerometer = require('ripple/accelerometer'),
+    event = require('ripple/event'),
+    Rotation = require('ripple/platform/w3c/1.0/Rotation'),
+    Acceleration = require('ripple/platform/w3c/1.0/Acceleration'),
+    _mouseDown,
+    _shiftKeyDown,
+    _offsets = {
+        x: 0,
+        y: 0,
+        z: -9.81,
+    },
+    _oldX,
+    _oldY,
+    _oldAlphaX,
+    _shape =
+        //
+        // The front side
+        //
+        // x, y, z      x, y, z         x, y, z
+        // for some strange reason for y -100 is top, 100 is bottom
+        "-30,30,10,     30,30,10,       30,60,10,       100,100,100,-1,0;" + // top left, top right, bottom right - of the right triangle
+        "-30,30,10,     30,60,10,       -30,60,10,      100,100,100,-1,0;" + // top left, right bottom, left bottom - of the left triangle
+        // front side "the phone display"
+        "-20,-50,11,    20,-50,11,      20,20,11,       100,100,100,-1,0;" +
+        "-20,-50,11,    20,20,11,       -20,20,11,      100,100,100,-1,0;" +
+        // below the display
+        "-30,30,10,     30,20,10,       30,30,10,       0,0,0,-1,0;" +
+        "-30,30,10,     -30,20,10,      30,20,10,       0,0,0,-1,0;" +
+        // above the display
+        "-30,-60,10,    30,-60,10,      30,-50,10,      0,0,0,-1,0;" +
+        "-30,-60,10,    30,-50,10,      -30,-50,10,     0,0,0,-1,0;" +
+        // left of the display
+        "-30,-50,10,    -20,-50,10,     -20,20,10,      0,0,0,-1,0;" +
+        "-30,-50,10,    -20,20,10,      -30,20,10,      0,0,0,-1,0;" +
+        // right of the display
+        "20,-50,10,     30,-50,10,      30,20,10,       0,0,0,-1,0;" +
+        "20,-50,10,     30,20,10,       20,20,10,       0,0,0,-1,0;" +
+
+
+        // back side, opposite side to the above one
+        "-30,-60,-10,   30,60,-10,      30,-60,-10,     0,0,0,-1,0;" +
+        "-30,-60,-10,   -30,60,-10,     30,60,-10,      0,00,-1,0;" +
+        // right side
+        "30,-60,-10,    30,60,-10,      30,60,10,       50,50,80,-1,0;" +
+        "30,-60,-10,    30,60,10,       30,-60,10,      50,50,80,-1,0;" +
+        // left side
+        "-30,-60,-10,   -30,60,10,      -30,60,-10,     50,50,80,-1,0;" +
+        "-30,-60,-10,   -30,-60,10,     -30,60,10,      50,50,80,-1,0;" +
+
+        // top
+        "30,-60,-10,    -30,-60,10, -30,-60,-10,    50,80,50,-1,0;" +
+        "30,-60,-10,    30,-60,10,      -30,-60,10, 50,80,50,-1,0;" +
+        // bottom
+        "30,60,-10, -30,60,-10,     -30,60,10,      80,50,50,-1,0;" +
+        "30,60,-10, -30,60,10,      30,60,10,       80,50,50,-1,0";
+
+function _shakeDevice() {
+    window.setTimeout(goodVibrations.shakeDevice(8), 1);
+    accelerometer.shake();
+}
+
+function _updateAccelerometerPanel(motion) {
+    jQuery("#accelerometer-x").html(Math.round(motion.accelerationIncludingGravity.x * 100) / 100);
+    jQuery("#accelerometer-y").html(Math.round(motion.accelerationIncludingGravity.y * 100) / 100);
+    jQuery("#accelerometer-z").html(Math.round(motion.accelerationIncludingGravity.z * 100) / 100);
+    jQuery("#accelerometer-alpha").html(Math.round(motion.orientation.alpha));
+    jQuery("#accelerometer-beta").html(Math.round(motion.orientation.beta));
+    jQuery("#accelerometer-gamma").html(Math.round(motion.orientation.gamma));
+}
+
+function _updateCanvas(a, b, g) {
+    ThreeDee.loadMesh(_shape);
+    g = g || 0;
+    ThreeDee.rotate(0, g, 0);
+    ThreeDee.rotate(b, 0, a);
+    ThreeDee.backface();
+    ThreeDee.shade();
+    ThreeDee.zSort();
+    Draw.initialize(document.querySelector("#accelerometer-canvas"));
+    Draw.clear(0, 0, 480, 300);
+    Draw.drawScene(ThreeDee.getTranslation(), 3);
+}
+
+function _createCanvas() {
+    var node = document.querySelector("#accelerometer-canvas"),
+        x = 0, y = 0, z = -9.81,
+        alpha = 0, beta = 0, gamma = 0,
+        cosX, sinX, cosY, sinY,
+        deltaAlpha = 360;
+
+    ThreeDee.setCenter(150, 100);
+    ThreeDee.setLight(-300, -300, 800);
+
+    node.addEventListener("mousemove", function (e) {
+        if (!_mouseDown)
+            return;
+
+        if (!_shiftKeyDown) {
+            _offsets.x = (_offsets.x + _oldX - e.offsetX) % 360;
+            _offsets.y = (_offsets.y + _oldY - e.offsetY) % 360;
+
+            alpha = alpha || 0;
+
+            // enforce gamma in [-90,90] as per w3c spec
+            gamma = -_offsets.x;
+            if (gamma < -90) {
+                gamma = -90;
+            }
+            if (gamma > 90) {
+                gamma = 90;
+            }
+
+            // enforce beta in [-180,180] as per w3c spec
+            beta = -_offsets.y % 360;
+            if (beta < -180) {
+                beta += 360;
+            }
+            else if (beta >= 180) {
+                beta -= 360;
+            }
+
+            cosX = Math.cos((gamma) * (Math.PI / 180));
+            sinX = Math.sin((gamma) * (Math.PI / 180));
+            cosY = Math.cos((beta) * (Math.PI / 180));
+            sinY = Math.sin((beta) * (Math.PI / 180));
+            x = 9.81 * cosY * sinX;
+            y = -9.81 * sinY;
+            z = -9.81 * cosY * cosX;
+
+        }
+        else {
+            deltaAlpha = (deltaAlpha - (_oldAlphaX - e.offsetX) * 2.5) % 360;
+            alpha = (360 - deltaAlpha) % 360;
+        }
+
+        _oldX = e.offsetX;
+        _oldY = e.offsetY;
+        _oldAlphaX = e.offsetX;
+
+        _updateCanvas(deltaAlpha, -beta, gamma);
+        accelerometer.setInfo({
+            x: x,
+            y: y,
+            z: z,
+            alpha: alpha,
+            beta: beta,
+            gamma: gamma
+        });
+
+    });
+
+    node.addEventListener("mousedown", function (e) {
+        _oldX = e.offsetX;
+        _oldY = e.offsetY;
+        if (_shiftKeyDown) {
+            _oldAlphaX = _oldX;
+        }
+        _mouseDown = true;
+    });
+
+    node.addEventListener("mouseup", function (e) {
+        _mouseDown = false;
+    });
+
+    node.addEventListener("dblclick", function (e) {   
+        x = 0;
+        y = 0;
+        z = -9.81;
+        alpha = 0;
+        beta = 0;
+        gamma = 0;
+        deltaAlpha = 360;
+        _resetAccelerometer();
+    });
+
+    document.addEventListener("mouseup", function (e) {
+        //Catch mouseup events that fire when outside canvas bounds
+        _mouseDown = false;
+    });
+
+    document.addEventListener("keydown", function (e) {
+        if (e.keyCode === 16) { // Shift Key            
+            _shiftKeyDown = true;
+        }
+    });
+
+    document.addEventListener("keyup", function (e) {
+        if (e.keyCode === 16) { // Shift Key
+            _shiftKeyDown = false;
+        }
+    });    
+}
+
+function _resetAccelerometer() {    
+    _updateCanvas(0, 0);
+    _oldX = 0;
+    _oldY = 0;
+    _oldAlphaX = 0;
+    _offsets = {
+        x: 0,
+        y: 0,
+        z: -9.81,
+    };
+    accelerometer.setInfo({
+        acceleration: new Acceleration(0, 0, 0),
+        accelerationIncludingGravity: new Acceleration(0, 0, -9.81),
+        rotationRate: new Rotation(0, 0, 0),
+        orientation: new Rotation(0, 0, 0),
+        timestamp: new Date().getTime()
+    });
+}
+
+module.exports = {
+    panel: {
+        domId: "accelerometer-container",
+        collapsed: true,
+        pane: "left",
+        titleName: "Accelerometer",
+        display: true
+    },
+    initialize: function () {
+        _createCanvas();
+        
+        _resetAccelerometer();
+
+        _updateAccelerometerPanel(accelerometer.getInfo());
+
+        jQuery("#accelerometer-shake").click(_shakeDevice);
+
+        event.on("AccelerometerInfoChangedEvent", _updateAccelerometerPanel, this);
+    }
+};
+
+});
+require.define('ripple/ui/plugins/phone', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    Phone = require('ripple/platform/webworks.handset/2.0.0/client/Phone'),
+    CallLog = require('ripple/platform/webworks.handset/2.0.0/client/CallLog'),
+    event = require('ripple/event'),
+    _console = require('ripple/console'),
+    eventSelect = document.getElementById("phone-event-types"),
+    eventErrorContainer = document.getElementById("phone-event-error-container"),
+    eventErrorSelect = document.getElementById("phone-event-error-types");
+
+function _firePhoneLogEvents(type, number, error) {
+    if (type === Phone.CB_CALL_INITIATED ||
+        type === Phone.CB_CALL_ANSWERED) {
+        event.trigger("PhoneCallLogAdded", [{
+            date: new Date(),
+            number: number,
+            status: CallLog.STATUS_NORMAL,
+            type: CallLog.TYPE_RECEIVED_CALL
+        }], true);
+    } else if (type === Phone.CB_CALL_ENDED_BYUSER ||
+                type === Phone.CB_CALL_FAILED) {
+        event.trigger("PhoneCallLogAdded", [{
+            date: new Date(),
+            number: number,
+            status: CallLog.STATUS_NORMAL,
+            type: CallLog.TYPE_PLACED_CALL
+        }], true);
+    }
+}
+
+function _updateActiveCalls(type, number, error) {
+    if (type === Phone.CB_CALL_INITIATED ||
+        type === Phone.CB_CALL_CONNECTED ||
+        type === Phone.CB_CALL_CONFERENCECALL_ESTABLISHED ||
+        type === Phone.CB_CALL_DIRECTCONNECT_CONNECTED ||
+        type === Phone.CB_CALL_ANSWERED) {
+        event.trigger("PhoneCallInitiated", [{
+            id: number,
+            onhold: false,
+            outgoing: false,
+            recipient: {
+                name: "",
+                number: String(number)
+            }
+        }], true);
+    } else if (type === Phone.CB_CALL_ENDED_BYUSER ||
+                type === Phone.CB_CALL_FAILED ||
+                type === Phone.CB_CALL_DISCONNECTED ||
+                type === Phone.CB_CONFERENCECALL_DISCONNECTED ||
+                type === Phone.CB_CALL_DIRECTCONNECT_DISCONNECTED) {
+        event.trigger("PhoneCallEnded", [{
+            id: number
+        }], true);
+    }
+}
+
+module.exports = {
+    panel: {
+        domId: "phone-container",
+        collapsed: true,
+        pane: "right"
+    },
+    initialize: function (prev, baton) {
+        utils.forEach(Phone, function (value, prop) {
+            if (prop.match(/^CB_/)) {
+                eventSelect.appendChild(utils.createElement("option", {
+                    value: value,
+                    innerHTML: prop.replace(/^CB_(CALL_)?/, "")
+                }));
+            }
+
+            if (prop.match(/^CALL_ERROR_/)) {
+                eventErrorSelect.appendChild(utils.createElement("option", {
+                    value: value,
+                    innerHTML: prop.replace(/^CALL_ERROR_/, "")
+                }));
+            }
+        });
+
+        document.getElementById("phone-event-types").addEventListener("change", function () {
+            eventErrorContainer.setAttribute("style", parseInt(eventSelect.value, 10) === Phone.CB_CALL_FAILED ? "" : "display: none");
+        });
+
+        document.getElementById("phone-logs-clear").addEventListener("click", function () {
+            event.trigger("PhoneCallLogReset");
+        });
+
+        document.getElementById("phone-event-send").addEventListener("click", function () {
+            var type = parseInt(eventSelect.value, 10),
+                error = type === Phone.CB_CALL_FAILED ? eventErrorSelect.value : undefined,
+                callId = document.getElementById("phone-call-id").value;
+
+            _firePhoneLogEvents(type, callId, error);
+            _updateActiveCalls(type, callId, error);
+
+            event.trigger("PhoneEvent", [type, callId, error]);
+
+            _console.log("Fired PhoneEvent (type " + type +  ") CallID: " +
+                         callId + (error ? (" (error type " + error + ")") : ""));
+        }, false);
+    }
+};
+
+});
+require.define('ripple/ui/plugins/notifications', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    notifications = require('ripple/notifications');
+
+module.exports = {
+    initialize: function () {
+        jQuery("." + constants.NOTIFICATIONS.CLOSE_BUTTON_CLASS).bind("click", function () {
+            notifications.closeNotification();
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/widgetConfig', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    tooltip = require('ripple/ui/plugins/tooltip'),
+    platform = require('ripple/platform'),
+    widgetConfig = require('ripple/widgetConfig');
+
+function _buildConfigAccordionNode(node, accordionContainer, counter) {
+    var nodeDiv, nodeTitleH3, nodeContentDiv, tableString, attribute, child, result,
+        tableClass, nameClass, attributeNameClass, messageClass, nameId, messageId, attributeName, attributeValue, attributeMessage,
+        helpText = {},
+        nodeCounter = 0,
+        attributeCounter = 0,
+        moreNodes = node.validationResult,
+        createTooltip = function (value, index) {
+            tooltip.create("#" +  index, value);
+        };
+
+    while (moreNodes) {
+        result = node.validationResult[nodeCounter];
+
+        if (!result) {
+            // this should never happen
+            return;
+        }
+
+        // the container of the entire accordion block
+        nodeDiv = utils.createElement("div", {
+            "id": "config-accordion-node-content-" + counter + "-" + nodeCounter,
+            "class": "ui-corner-all"
+        });
+
+        // the header bar of the accordion block
+        nodeTitleH3 = utils.createElement("h3", {
+            "id": "config-accordion-node-title-" + counter + "-" + nodeCounter,
+            "class": "config-accordion-node-title"
+        });
+
+        nodeTitleH3.appendChild(utils.createElement("a", {
+            href: "#",
+            innerText: node.nodeName,
+            "class": constants.CONFIG.SUCCESS_CSS[(result.valid === undefined) ? "missing" : result.valid.toString()]
+        }));
+        nodeDiv.appendChild(nodeTitleH3);
+
+        if (node.helpText) {
+            helpText[nodeTitleH3.id] = node.helpText;
+        }
+
+        nodeContentDiv = utils.createElement("div");
+
+        // display node value (add tool tip if exists)
+        if (node.type || (!node.type && result && result.value)) {
+            nodeContentDiv.appendChild(utils.createElement("div", {
+                "id": "config-accordion-node-content-value-" + counter + "-" + nodeCounter,
+                "class": "config-accordion-node-content-value",
+                "innerHTML": "<span>Value:</span>" + (result.value || "")
+            }));
+
+            if (node.helpValueText) {
+                helpText["config-accordion-node-content-value-" + counter + "-" + nodeCounter] = node.helpValueText;
+            }
+        }
+
+        // display node message if failed validation
+        if (result && result.message) {
+            nodeContentDiv.appendChild(utils.createElement("div", {
+                "id": "config-accordion-node-content-value-message-" + counter + "-" + nodeCounter,
+                "class": "config-accordion-node-content-value-message ui-text-fail",
+                "innerHTML": "<span>Message:</span>" + result.message
+            }));
+        }
+
+        // display node attributes with name, value, message if failed validation
+        if (result.attributes) {
+            nodeContentDiv.appendChild(utils.createElement("div", {
+                "id": "config-accordion-node-content-attributes-title-" + counter + "-" + nodeCounter,
+                "class": "config-accordion-node-content-attributes-title",
+                "innerHTML": "Attributes..."
+            }));
+
+            tableClass = "preferences-table";
+            nameClass = "config-attributes-name-value";
+            attributeNameClass = "ui-text-label";
+            messageClass = "config-attributes-message";
+
+            tableString = '<table class="' + tableClass + ' ui-widget-content">';
+            for (attribute in result.attributes) {
+                if (result.attributes.hasOwnProperty(attribute)) {
+                    nameId = "config-accordion-node-content-attributes-table-name-" + counter + "-" + nodeCounter + "-" + attributeCounter;
+                    messageId = "config-accordion-node-content-attributes-table-message-" + counter + "-" + nodeCounter + "-" + attributeCounter;
+                    attributeName = result.attributes[attribute].attributeName;
+                    attributeValue = result.attributes[attribute].value || "&nbsp;";
+                    attributeMessage = result.attributes[attribute].message || null;
+
+                    tableString += '<tr class="' + nameClass + '" id="' + nameId + '">' +
+                            '<td class="' + attributeNameClass + '">' + attributeName + '</td>' +
+                            '<td>' + attributeValue + '</td></tr>';
+
+                    if (node.attributes[attributeName].helpText) {
+                        helpText[nameId] = node.attributes[attributeName].helpText;
+                    }
+
+                    if (attributeMessage !== null) {
+                        tableString += "<tr class=" + messageClass + " id=" + messageId + "><td colspan=\"2\">" +
+                                attributeMessage + "</td></tr>";
+                    }
+                    attributeCounter++;
+                }
+            }
+            tableString += "</table>";
+
+            nodeContentDiv.innerHTML += tableString;
+        }
+
+
+        nodeDiv.appendChild(nodeContentDiv);
+        accordionContainer.appendChild(nodeDiv);
+
+        utils.forEach(helpText, createTooltip);
+
+        nodeCounter ++;
+
+        if (!node.validationResult[nodeCounter]) {
+            nodeCounter = 0;
+            moreNodes = false;
+        }
+    }
+
+    if (node.children) {
+        for (child in node.children) {
+            if (node.children.hasOwnProperty(child)) {
+                counter ++;
+                _buildConfigAccordionNode(node.children[child], accordionContainer, counter);
+            }
+        }
+    }
+}
+
+function _initializeConfigResultsView(results) {
+    try {
+        var rootNode,
+            accordionContainer = document.getElementById("widget-config");
+
+        accordionContainer.innerHTML = "";
+        if (!results) {
+            accordionContainer.appendChild(utils.createElement("div", {
+                "class": "config-accordion-node-title " + constants.CONFIG.SUCCESS_CSS["false"],
+                "innerHTML": "Expected to find a configuration file for your widget, but none is present. Please create" +
+                        " a configuration file with the following name in the root directory of your widget: " +
+                        platform.current().fileName
+            }));
+            return;
+        }
+
+        rootNode = results[results.rootElement];
+
+        _buildConfigAccordionNode(rootNode, accordionContainer, 0);
+
+        jQuery(function () {
+            var stop = false;
+            jQuery("#widget-config h3").click(function (event) {
+                if (stop) {
+                    event.stopImmediatePropagation();
+                    event.preventDefault();
+                    stop = false;
+                }
+            });
+            jQuery("#widget-config").accordion("destroy").accordion({
+                header: "> div > h3",
+                autoHeight: false
+            });
+        });
+    } catch (e) {
+        exception.handle(e, true);
+    }
+}
+
+event.on("FrameHistoryChange", function (url) {
+    module.exports.initialize();
+});
+
+module.exports = {
+    panel: {
+        domId: "config-container",
+        collapsed: true,
+        pane: "right",
+        titleName: "Feature Configuration",
+        display: true
+    },
+    initialize: function () {
+        var results = widgetConfig.getValidationResults();
+        _initializeConfigResultsView(results);
+    }
+};
+
+});
+require.define('ripple/ui/plugins/settings-dialog', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    platform = require('ripple/platform'),
+    notifications = require('ripple/notifications'),
+    transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
+    required = {
+        build: {
+            "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName"],
+            "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName"]
+        },
+        sign: {
+            "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName", "csk_password", "p12_password", "bundle_number"],
+            "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName", "signingPassword"]
+        },
+        launch: {
+            "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName", "device", "devicePassword"],
+            "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName", "simulator"]
+        }
+    },
+    _settings = {
+        get: function () {
+            var settings = db.retrieveObject("build-settings", platform.getPersistencePrefix()) || {};
+            settings.debug = !!settings["remoteInspector"];
+
+            return settings;
+        },
+        save: function (settings) {
+            db.saveObject("build-settings", settings, platform.getPersistencePrefix());
+        }
+    },
+    //TODO: Restore this line once framework issue is resolved
+    //port = window.stagewebview ? stagewebview.serverPort : "9900",
+    port = "9900",
+    host = "http://127.0.0.1:" + port + "/ripple",
+    progressContainer = jQuery("#options-progress"),
+    progressInterval,
+    _passwordFields = [
+        "signingPassword",
+        "devicePassword",
+        "csk_password",
+        "p12_password"
+    ],
+    _checkboxFields = [
+        "remoteInspector"
+    ],
+    _passwords = {},
+    _self;
+
+function missing(settings, action) {
+    return required[action][platform.current().id].filter(function (field) {
+        return !settings.hasOwnProperty(field);
+    });
+}
+
+function _isPasswordField(id) {
+    var match = typeof id === "string" && new RegExp("^" + id + "$", "i");
+    return match && utils.some(_passwordFields, function (name) {
+        return match.test(name);
+    });
+}
+
+function _isCheckboxField(id) {
+    var match = typeof id === "string" && new RegExp("^" + id + "$", "i");
+    return match && utils.some(_checkboxFields, function (name) {
+        return match.test(name);
+    });
+}
+
+function table(action) {
+    var _table = $("<table class='panel-table'>"),
+        _row = {
+            row: function (item, desc, opts) {
+                var id = "settings-field-" + item.toLowerCase(),
+                    input = "",
+                    save = function () {
+                        var s = _settings.get(),
+                            v = $("#" + id).val(),
+                            val = opts.type === "number" ? parseInt(v, 10) : v;
+
+                        if (_isCheckboxField(item)) {
+                            s[item] = $("#" + id).prop("checked");
+                        }
+                        else if (val) {
+                            (_isPasswordField(item) ? _passwords : s)[item] = val;
+                        }
+                        else {
+                            delete s[item];
+                        }
+                        _settings.save(s);
+                    },
+                    row;
+
+                opts = opts || { type: "text" };
+
+                switch (opts.type) {
+                case "select":
+                    input = "<select id='" + id + "' class='ui-state-default ui-corner-all' style='width:100%'/>";
+                    break;
+                case "span":
+                    input = "<span id = '" + id + "'>" + opts.text + "</span>";
+                    break;
+                default:
+                    input = "<input id='" + id + "' type='" + opts.type + "' class='ui-state-default ui-corner-all' style='width:100%' />";
+                    break;
+                }
+
+                row = $("<tr>" +
+                    "<td><label for='" + id + "' class='ui-text-label'>" + desc + "</label></td>" +
+                    "<td>" + input + "</td>" +
+                "</tr>");
+
+                row.appendTo(_table);
+
+                //bind save handlers to the row
+                utils.bindAutoSaveEvent(row.find("#" + id).change(save), save);
+
+                return _row;
+            },
+            appendTo: function (id) {
+                var fs = $("<fieldset><legend class='cap-text'>" + action + "</legend></fieldset>");
+
+                $(_table).appendTo(fs);
+                fs.appendTo($(id));
+            }
+        };
+
+    return _row;
+}
+
+function create() {
+    var build = table('build'),
+        sign = table('sign'),
+        launch = table('launch');
+
+    build
+        .row("sdk", "SDK Path")
+        .row("projectPath", "Project Root")
+        .row("projectName", "Archive Name")
+        .row("outputPath", "Output Folder")
+        .row("remoteInspector", "Enable Remote Web Inspector", {
+            type: "checkbox"
+        })
+        .appendTo("#settings-tabs-build");
+
+    if (platform.current().id === "webworks.handset") {
+        sign.row("signingPassword", "Password", {
+            type: "password"
+        });
+
+        launch.row("simulator", "Simulator", {
+            type: "select"
+        });
+
+        launch.row("simulatorstatus", "Simulator", {
+            type: "span",
+            text: "Searching for simulators ..."
+        });
+    }
+    else if (platform.current().id === "webworks.tablet") {
+        sign.row("csk_password", "CSK Password", {
+            type: "password"
+        });
+        sign.row("p12_password", "P12 Password", {
+            type: "password"
+        });
+        sign.row("bundle_number", "Bundle Number", {
+            type: "number"
+        });
+
+        launch.row("device", "Playbook IP");
+        launch.row("devicePassword", "Playbook Password", {
+            type: "password"
+        });
+    }
+
+    sign.appendTo("#settings-tabs-build");
+    launch.appendTo("#settings-tabs-build");
+
+    $("#settings-field-simulator").parent().parent().hide();
+}
+
+function populate(settings) {
+    var fill = function (action, prop) {
+        var element = $("#settings-field-" + prop.toLowerCase());
+
+        if (_isPasswordField(prop)) {
+            element.val(_passwords[prop]);
+        }
+        else if (_isCheckboxField(prop)) {
+            element.prop("checked", settings[prop]);
+        }
+        else {
+            element.val(settings[prop]);
+        }
+    };
+
+    fill("build", "sdk");
+    fill("build", "projectPath");
+    fill("build", "outputPath");
+    fill("build", "projectName");
+    fill("build", "remoteInspector");
+
+    fill("sign", "signingPassword");
+    fill("sign", "csk_password");
+    fill("sign", "p12_password");
+    fill("sign", "bundle_number");
+
+    fill("launch", "simulator");
+    fill("launch", "device");
+    fill("launch", "devicePassword");
+}
+
+function url(action) {
+    var target = "";
+
+    switch (platform.current().id) {
+    case "webworks.tablet":
+        target = "tablet";
+        break;
+    case "webworks.handset":
+        target = "smartphone";
+        break;
+    }
+
+    return host + "/" + action + "/" + target;
+}
+
+function enable(action) {
+    $("#options-menu-" + action).removeClass("not-ready");
+    if (action === "launch") {
+        $("#settings-field-simulatorstatus").parent().parent().hide();
+        $("#settings-field-simulator").parent().parent().show();
+    }
+}
+
+function disable(action) {
+    $("#options-menu-" + action).addClass("not-ready");
+    if (action === "launch") {
+        $("#settings-field-simulatorstatus").parent().parent().show();
+        $("#settings-field-simulator").parent().parent().hide();
+    }
+}
+
+function getSimulators() {
+    if (!_settings.get().sdk) {
+        $("#settings-field-simulatorstatus").text("");
+        disable("launch");
+        return;
+    }
+
+    $.ajax({
+        url: host + "/simulators",
+        type: "GET",
+        async: true,
+        data: _settings.get(), // assume no passwords here
+        success: function (resp) {
+            var sims = resp.data.simulators;
+
+            $("#settings-field-simulator").empty();
+            if (sims.length > 0) {
+                $(resp.data.simulators.map(function (sim) {
+                    return "<option value='" + sim + "'>" + sim + "</option>";
+                }).join()).appendTo("#settings-field-simulator");
+
+                enable("launch");
+            }
+            else {
+                disable("launch");
+                $("#settings-field-simulatorstatus").text("No simulators found :(");
+            }
+        },
+        error: function () {
+            disable("launch");
+            $("#settings-field-simulatorstatus").text("Error attempting to get simulators :(");
+        }
+    });
+}
+
+function _startProgress() {
+    if (progressInterval) {
+        window.clearInterval(progressInterval);
+    }
+    progressInterval = window.setInterval(function () {
+        if (progressContainer.html().length === 5) {
+            progressContainer.html(".");
+        }
+        else {
+            progressContainer.html(progressContainer.html() + ".");
+        }
+    }, 250);
+}
+
+function _endProgress() {
+    window.clearInterval(progressInterval);
+    progressInterval = null;
+    progressContainer.html("");
+}
+
+
+_self = {
+    initialize: function () {
+        $("#settings-dialog").dialog({
+            autoOpen: false,
+            modal: true,
+            width: 700,
+            title: "Settings",
+            position: 'center'
+        }).hide();
+
+        $("#settings-tabs").tabs();
+        $("#settings-action").button();
+
+        create();
+
+        if (platform.current().id === "webworks.handset") {
+            enable("build");
+            enable("sign");
+            enable("settings");
+
+            getSimulators();
+            $("#settings-field-sdk").change(getSimulators);
+        }
+        else if (platform.current().id === "webworks.tablet") {
+            enable("build");
+            enable("sign");
+            enable("launch");
+            enable("settings");
+        }
+    },
+
+    can: function (action) {
+        var settings = {};
+
+        utils.mixin(_settings.get(), settings);
+        utils.mixin(_passwords, settings);
+
+        return missing(settings, action).length === 0;
+    },
+
+    value: function (prop) {
+        var settings = {};
+
+        utils.mixin(_settings.get(), settings);
+        return settings[prop];
+    },
+
+    show: function (action) {
+        var settings = {};
+
+        utils.mixin(_settings.get(), settings);
+        utils.mixin(_passwords, settings);
+
+        populate(settings);
+
+        $("#settings-dialog").dialog("open");
+        $("#settings-action").button("option", "label", action || "")[action ? "show" : "hide"]();
+
+        if (action) {
+            missing(settings, action).forEach(function (field) {
+                $("#settings-field-" + field.toLowerCase()).effect("highlight", {color: "red"}, 1500);
+            });
+
+            $("#settings-action").unbind("click").click(function () {
+                if (_self.can(action)) {
+                    _self.perform(action);
+                    $("#settings-dialog").dialog("close");
+                }
+                else {
+                    _self.show(action);
+                }
+            });
+        }
+    },
+
+    perform: function (action) {
+        var settings = _settings.get(),
+            data = {},
+            poll = function (resp) {
+                var notifications = require("ripple/notifications");
+
+                if (resp && resp.code !== 0) {
+                    notifications.openNotification("error", "Build request failed with message: " + resp.msg);
+                    _endProgress();
+                }
+                else {
+                    if (resp && resp.data.status === "building") {
+                        setTimeout(function () {
+                            $.ajax({
+                                url: host + "/build_status/" + resp.data.id,
+                                type: "GET",
+                                async: true,
+                                success: poll,
+                                error: function (error, errorText) {
+                                    notifications.openNotification("error", "Build request failed with message: " + errorText);
+                                    _endProgress();
+                                }
+                            });
+                        }, 500);
+                    }
+                    else {
+                        if (action.match(/sign/)) {
+                            settings["bundle_number"] = $("#settings-field-bundle_number").val(parseInt($("#settings-field-bundle_number").val(), 10) + 1).val();
+                            _settings.save(settings);
+                        }
+                        notifications.openNotification("normal", "Build succeeded!");
+                        _endProgress();
+                    }
+                }
+            };
+
+        utils.mixin(settings, data);
+        utils.mixin(_passwords, data);
+
+        $.ajax({
+            url: url(action),
+            type: "POST",
+            data: data,
+            async: true,
+            success: function (msg) {
+                _startProgress();
+                poll(msg);
+            },
+            error: function (xhr, errorText) {
+                notifications.openNotification("error", "Build request failed with message: " + errorText);
+            }
+        });
+    }
+};
+
+module.exports = _self;
+
+});
+require.define('ripple/ui/plugins/multimedia', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    volumeField = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_FIELD_ID),
+    volume = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_SLIDER_ID);
+
+module.exports = {
+    panel: {
+        domId: "multimedia-container",
+        collapsed: true,
+        pane: "left"
+    },
+    initialize: function () {
+        var volumeField = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_FIELD_ID),
+            volume = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_SLIDER_ID);
+
+        event.on("MultimediaVolumeChanged", function (volume) {
+            volumeField.innerText = volume > 9 ? volume : "0" + volume;
+            if (volume.value !== volume) {
+                volume.value = volume;
+            }
+        });
+
+        volume.addEventListener('change', function () {
+            event.trigger("MultimediaVolumeChanged", [this.value], true);
+        }, false);
+
+        event.on("MultimediaAudioStateChanged", function updateIsAudioPlaying(state) {
+            document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PLAYING_FIELD_ID).innerHTML = state === constants.MULTIMEDIA.AUDIO_STATES.PLAYING;
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/nfc', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('ripple/db'),
+    event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    _NFC_TAG = "tizen1.0-nfc-tag",
+    _NFC_PEER = "tizen1.0-nfc-peer",
+    _NFC_OUTPUT_MESSAGE = "tizen1.0-nfc-output-message",
+    powered = false,
+    polling = false,
+    isConnected = false,
+    _tagNDEF = {
+        type: "GENERIC_TARGET",
+        isSupportedNDEF: true,
+        ndefSize: 2,
+        ndefs: [{
+            recordCount: 2,
+            records: [{
+                tnf: 1,
+                type: "TypeA",
+                id: "ID001",
+                payload: "This is 1st payload"
+            }, {
+                tnf: 1,
+                type: "TypeA",
+                id: "ID002",
+                payload: "This is 2nd payload"
+            }]
+        },
+            {
+            recordCount: 2,
+            records: [{
+                tnf: 1,
+                type: "TypeA",
+                id: "ID001",
+                payload: "This is 1st payload"
+            }, {
+                tnf: 1,
+                type: "TypeA",
+                id: "ID002",
+                payload: "This is 2nd payload"
+            }]
+        }]
+    },
+    _tagRaw = {
+        type: "GENERIC_TARGET",
+        isSupportedNDEF: false,
+        rawData : ""
+    },
+    _peerNDEF = {
+        ndef: {
+            recordCount: 2,
+            records: [{
+                tnf: 1,
+                type: "TypeA",
+                id: "ID001",
+                payload: "This is 1st payload"
+            }, {
+                tnf: 1,
+                type: "TypeA",
+                id: "ID002",
+                payload: "This is 2nd payload"
+            }]
+        }
+    };
+
+function elementEnableDisableSetting(prop) {
+    jQuery("#nfc-attach-msg").text("\xa0");
+    jQuery("#nfc-peer-send-msg").text("\xa0");
+    if (prop && prop.power !== undefined && prop.power !== null) {
+        if (prop.power) {
+            $("#nfc-polling").removeAttr("disabled");
+            $("#nfc-main-container").show();
+        } else {
+            $("#nfc-polling").attr("disabled", "disabled");
+            $("#nfc-type").removeAttr("disabled");
+            $("#nfc-main-container").hide();
+        }
+    }
+    if (prop && prop.connectedState !== undefined && prop.connectedState !== null) {
+        if (prop.connectedState) {
+            $("#nfc-type").attr("disabled", "disabled");
+            $("#nfc-tag-type-text").text($("#nfc-tag-type option:selected").text());
+            $("#nfc-tag-type").hide();
+            $("#nfc-tag-type-text").show();
+            $("#nfc-tag-NDEF-support-text").text($("#nfc-tag-NDEF-support option:selected").text());
+            $("#nfc-tag-NDEF-support").hide();
+            $("#nfc-tag-NDEF-support-text").show();
+            $("#nfc-raw-data").attr("disabled", "disabled");
+        } else {
+            $("#nfc-type").removeAttr("disabled");
+            $("#nfc-tag-type").show();
+            $("#nfc-tag-type-text").hide();
+            $("#nfc-tag-NDEF-support").show();
+            $("#nfc-tag-NDEF-support-text").hide();
+            $("#nfc-raw-data").removeAttr("disabled");
+        }
+    }
+}
+
+function _initializeElements() {
+
+    jQuery(function () {
+        var stop = false,
+            isSupportNDEF, type;
+
+        jQuery("nfc-tag-ndef-container h3").click(function (event) {
+            if (stop) {
+                event.stopImmediatePropagation();
+                event.preventDefault();
+                stop = false;
+            }
+        });
+        jQuery("#nfc-tag-ndef-container").accordion("destroy").accordion({
+            header: "> div > h3",
+            autoHeight: false
+        });
+        jQuery("nfc-nfcpeer h3").click(function (event) {
+            if (stop) {
+                event.stopImmediatePropagation();
+                event.preventDefault();
+                stop = false;
+            }
+        });
+        jQuery("#nfc-nfcpeer").accordion("destroy").accordion({
+            header: "> div > h3",
+            autoHeight: false
+        });
+        jQuery("#nfc-tag-NDEF-support").bind("change", function () {
+            isSupportNDEF = jQuery("#nfc-tag-NDEF-support").val();
+            if (isSupportNDEF === "Yes") {
+                jQuery("#nfc-tag-ndef-container").fadeIn();
+                jQuery("#nfc-tag-raw-container").hide();
+            } else {
+                jQuery("#nfc-tag-ndef-container").hide();
+                jQuery("#nfc-tag-raw-container").fadeIn();
+            }
+        });
+        jQuery("#nfc-type").bind("change", function () {
+            type = jQuery("#nfc-type").val();
+            if (type === "Tag") {
+                jQuery("#nfc-nfctag").fadeIn();
+                jQuery("#nfc-nfcpeer").hide();
+            } else {
+                jQuery("#nfc-nfctag").hide();
+                jQuery("#nfc-nfcpeer").fadeIn();
+            }
+            elementEnableDisableSetting();
+        });
+        jQuery("#nfc-power").bind("change", function () {
+            var status;
+            status = jQuery("#nfc-power").val() === "On" ? true : false;
+            event.trigger("nfc-power-setting", [status]);
+        });
+        jQuery("#nfc-polling").bind("change", function () {
+            var status;
+            status = jQuery("#nfc-polling").val() === "On" ? true : false;
+            event.trigger("nfc-polling-setting", [status]);
+        });
+        jQuery("#nfc-attach").bind("click", function () {
+            var type, isAttached;
+            isAttached = jQuery("#nfc-attach").children().text() === "Attach" ? true : false;
+            jQuery("#nfc-attach-msg").text("\xa0");
+
+            if (!polling && isAttached) {
+                jQuery("#nfc-attach-msg").text("Polling:Off, attach won't work");
+                return;
+            }
+            type = jQuery("#nfc-type").val();
+            event.trigger("nfc-attach-setting", [type, isAttached]);
+        });
+        jQuery("#nfc-peer-send").bind("click", function () {
+            jQuery("#nfc-peer-send-msg").text("\xa0");
+            if (!isConnected) {
+                jQuery("#nfc-peer-send-msg").text("Disconnected. Send won't work");
+                return;
+            }
+            db.saveObject(_NFC_PEER, _peerNDEF);
+            event.trigger("nfc-peer-sending-ndef", []);
+        });
+    });
+}
+
+module.exports = {
+    panel: {
+        domId: "nfc-container",
+        collapsed: true,
+        pane: "left",
+        titleName: "NFC",
+        display: true
+    },
+    initialize: function () {
+        _initializeElements();
+        event.on("nfc-power-changed", function (status) {
+            powered = status;
+            if (powered === true) {
+                $("#nfc-power").val("On");
+            } else {
+                $("#nfc-power").val("Off");
+            }
+            elementEnableDisableSetting({power: status});
+        });
+        event.on("nfc-polling-changed", function (status) {
+            polling = status;
+            if (polling === true) {
+                $("#nfc-polling").val("On");
+            } else {
+                $("#nfc-polling").val("Off");
+            }
+            elementEnableDisableSetting();
+        });
+        event.on("nfc-connectedState-changed", function (state) {
+            var i, type, isSupportedNDEF, str, bytes = [];
+            isConnected = state;
+            elementEnableDisableSetting({connectedState: state});
+            type = jQuery("#nfc-type").val();
+            if (state) {
+                jQuery("#nfc-attach").children().text("Detach");
+                jQuery("#nfc-tag-connection").text("Connected");
+                jQuery("#nfc-peer-connection").text("Connected");
+                if (type === "Tag") {
+                    isSupportedNDEF = jQuery("#nfc-tag-NDEF-support").val() === "Yes" ? true : false;
+                    if (isSupportedNDEF) {
+                        _tagNDEF.type = jQuery("#nfc-tag-type").val();
+                        db.saveObject(_NFC_TAG, _tagNDEF);
+                    } else {
+                        _tagRaw.type = jQuery("#nfc-tag-type").val();
+                        str = jQuery("#nfc-raw-data").val();
+                        for (i = 0; i < str.length; i++) {
+                            bytes.push(str.charCodeAt(i));
+                        }
+                        _tagRaw.rawData = bytes;
+                        db.saveObject(_NFC_TAG, _tagRaw);
+                    }
+                    event.trigger("nfc-tag-send", [true]);
+                } else {
+                    event.trigger("nfc-peer-send", [true]);
+                }
+            } else {
+                jQuery("#nfc-attach").children().text("Attach");
+                jQuery("#nfc-tag-connection").text("Disconnected");
+                jQuery("#nfc-peer-connection").text("Disconnected");
+                jQuery("#nfc-output").text("");
+                jQuery("#nfc-output-table").hide();
+                if (type === "Tag") {
+                    event.trigger("nfc-tag-send", [false]);
+                } else {
+                    event.trigger("nfc-peer-send", [false]);
+                }
+            }
+        });
+        event.on("nfc-output-msg", function () {
+            var msg;
+            msg = db.retrieve(_NFC_OUTPUT_MESSAGE);
+            jQuery("#nfc-output").text(msg);
+            jQuery("#nfc-output-table").show();
+        });
+    }
+};
+
+
+});
+require.define('ripple/ui/plugins/platformEvents', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var _console = require('ripple/console'),
+    platform = require('ripple/platform'),
+    event = require('ripple/event'),
+    exception = require('ripple/exception'),
+    utils = require('ripple/utils');
+
+module.exports = {
+    panel: {
+        domId: "platform-events-container",
+        collapsed: true,
+        pane: "right"
+    },
+    initialize: function () {
+        var eventSelect = document.getElementById("platform-events-select"),
+            spec = platform.current();
+
+        if (!spec.events) {
+            return;
+        }
+
+        utils.forEach(spec.events, function (method, name) {
+            eventSelect.appendChild(utils.createElement("option", {
+                "innerText": name,
+                "value": name
+            }));
+        });
+
+        jQuery("#platform-events-fire").click(function () {
+            var eventName = document.getElementById("platform-events-select").value,
+                args = spec.events[eventName].args ? document.getElementById("platform-events-args").value : null,
+                callback = spec.events[eventName].callback;
+
+            _console.log("fired event => " + eventName);
+
+            try {
+                callback(args);
+            } catch (e) {
+                exception.throwMaskedException(e);
+            }
+        });
+
+        jQuery(eventSelect).change(function () {
+            var argsSelect = jQuery("#platform-events-args"),
+                args = spec.events[this.value].args;
+
+            argsSelect.empty();
+
+            if (args) {
+                utils.forEach(spec.events[this.value].args, function (arg, index) {
+                    argsSelect.append(utils.createElement("option", {
+                        innerText: arg,
+                        value: index
+                    }));
+                });
+
+                argsSelect.show();
+            } else {
+                argsSelect.hide();
+            }
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/geoDB', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('ripple/db'),
+    utils = require('ripple/utils'),
+    lbs = require('ripple/platform/tizen/1.0/lbs_utils'),
+    _GEO_OBJECTS = "tizen1.0-geocode-objects",
+    _geoList, _currentGeo, _saveID, _showGeoDetail;
+
+function _getGeo() {
+    var geoList = [],
+        data = db.retrieveObject(_GEO_OBJECTS);
+
+    utils.forEach(data, function (geo) {
+        geoList.push(geo);
+    });
+    return geoList;
+}
+
+function _saveGeo() {
+    db.saveObject(_GEO_OBJECTS, _geoList);
+}
+
+function GeoEntry(addr, coord) {
+    var _self;
+    _self = {
+        address : addr || null,
+        coordinate : coord || null
+    };
+    return _self;
+}
+
+function _updateGeoDBSelect() {
+    var geoDBSelect = document.getElementById("geo-select"),
+        geoNode, i;
+
+    geoDBSelect.innerHTML = "";
+    for (i = 0; i < _geoList.length; i++) {
+        geoNode = utils.createElement("option", {
+            "innerText": "(" + _geoList[i].coordinate.latitude + ", " + _geoList[i].coordinate.longitude + ")",
+            "value": i
+        });
+        if (_currentGeo === Number(geoNode.value)) {
+            geoNode.selected = true;
+            _showGeoDetail(_geoList[_currentGeo].coordinate, _geoList[_currentGeo].address);
+        }
+        geoDBSelect.appendChild(geoNode);
+    }
+}
+
+function _showGeoDetail(coord, addr) {
+    jQuery("#geoDB-latitude").val(coord.latitude);
+    jQuery("#geoDB-longitude").val(coord.longitude);
+    jQuery("#geoDB-altitude").val(coord.altitude);
+    jQuery("#geoDB-accuracy").val(coord.accuracy);
+    jQuery("#geoDB-altitudeAccuracy").val(coord.altitudeAccuracy);
+    jQuery("#geoDB-heading").val(coord.heading);
+    jQuery("#geoDB-speed").val(coord.speed);
+
+    jQuery("#geoDB-country").val(addr.country);
+    jQuery("#geoDB-region").val(addr.region);
+    jQuery("#geoDB-county").val(addr.county);
+    jQuery("#geoDB-city").val(addr.city);
+    jQuery("#geoDB-street").val(addr.street);
+    jQuery("#geoDB-streetNumber").val(addr.streetNumber);
+    jQuery("#geoDB-premises").val(addr.premises);
+    jQuery("#geoDB-additionalInformation").val(addr.additionalInformation);
+    jQuery("#geoDB-postalCode").val(addr.postalCode);
+}
+
+function _changeGeoData() {
+    var id = Number(jQuery("#geo-select").val());
+    _currentGeo = id;
+    _showGeoDetail(_geoList[id].coordinate, _geoList[id].address);
+}
+
+function _triggerReadOnly(on) {
+    if (on === true) {
+        jQuery("#geoDB-table input").attr("readonly", "readonly");
+        jQuery("#geoDB-add").show();
+        jQuery("#geoDB-modify").show();
+        jQuery("#geoDB-delete").show();
+        jQuery("#geo-select").removeAttr("disabled");
+        jQuery("#geoDB-save").hide();
+        jQuery("#geoDB-cancel").hide();
+    } else {
+        jQuery("#geoDB-table input").removeAttr("readonly");
+        jQuery("#geoDB-add").hide();
+        jQuery("#geoDB-modify").hide();
+        jQuery("#geoDB-delete").hide();
+        jQuery("#geo-select").attr("disabled", "disabled");
+        jQuery("#geoDB-save").show();
+        jQuery("#geoDB-cancel").show();
+    }
+}
+
+function _addGeoData() {
+    _triggerReadOnly(false);
+    jQuery("#geoDB-table input").val("");
+    _saveID = _geoList.length;
+    jQuery("#geo-select").val("");
+}
+function _modifyGeoData() {
+    _triggerReadOnly(false);
+    _saveID = _currentGeo;
+}
+function _deleteGeoData() {
+    _geoList.splice(_currentGeo, 1);
+    _saveGeo();
+    _currentGeo = 0;
+    _updateGeoDBSelect();
+}
+function _saveGeoData() {
+    var entry;
+    entry = new GeoEntry(new lbs.StructuredAddress({
+        country: jQuery("#geoDB-country").val(),
+        region: jQuery("#geoDB-region").val(),
+        county: jQuery("#geoDB-county").val(),
+        city: jQuery("#geoDB-city").val(),
+        street: jQuery("#geoDB-street").val(),
+        streetNumber: jQuery("#geoDB-streetNumber").val(),
+        premises: jQuery("#geoDB-premises").val(),
+        additionalInformation: jQuery("#geoDB-additionalInformation").val(),
+        postalCode: jQuery("#geoDB-postalCode").val()
+    }),
+        new lbs.GeoCoordinates({
+        latitude: parseFloat(jQuery("#geoDB-latitude").val()),
+        longitude: parseFloat(jQuery("#geoDB-longitude").val()),
+        altitude: parseFloat(jQuery("#geoDB-altitude").val()),
+        accuracy: parseFloat(jQuery("#geoDB-accuracy").val()),
+        altitudeAccuracy: parseFloat(jQuery("#geoDB-altitudeAccuracy").val()),
+        heading: parseFloat(jQuery("#geoDB-heading").val()),
+        speed: parseFloat(jQuery("#geoDB-speed").val())
+    }));
+    if (_saveID === _geoList.length)
+        _geoList.push(entry);
+    else
+        _geoList[_saveID] = entry;
+    
+    _saveGeo();
+    _currentGeo = _saveID;
+    _updateGeoDBSelect();
+    _triggerReadOnly(true);
+}
+
+function _cancelGeoData() {
+    _triggerReadOnly(true);
+    _updateGeoDBSelect();
+}
+
+module.exports = {
+    panel: {
+        domId: "geoDB-container",
+        collapsed: true,
+        pane: "right"
+    },
+
+    initialize: function () {
+        _currentGeo = 0; // set _geoList[0] as default value
+        _geoList = _getGeo();
+        _updateGeoDBSelect();
+        _triggerReadOnly(true);
+
+        jQuery("#geo-select").bind("change", function () {
+            _changeGeoData();
+        });
+        jQuery("#geoDB-add").bind("click", function () {
+            _addGeoData();
+        });
+        jQuery("#geoDB-modify").bind("click", function () {
+            _modifyGeoData();
+        });
+        jQuery("#geoDB-delete").bind("click", function () {
+            _deleteGeoData();
+        });
+        jQuery("#geoDB-save").bind("click", function () {
+            _saveGeoData();
+        });
+        jQuery("#geoDB-cancel").bind("click", function () {
+            _cancelGeoData();
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/call', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    _exception = {
+        "unknown":           "Unknown",
+        "network":           "Network",
+        "unreachable":       "Unreachable",
+        "no-answer":         "No Answer",
+        "bad-number":        "Bad Number",
+        "number-not-in-use": "Number Not In Use",
+        "media":             "Media",
+        "no-sim":            "No Sim Card",
+        "account-down":      "Account Down",
+        "credit-down":       "Credit Down",
+        "barred":            "Barred",
+        "network-busy":      "Network Busy",
+        "network-down":      "Network Down"
+    },
+    _status = {
+        IDLE:       0,
+        DIALED:     1,
+        PLACED:     2,
+        INPROGRESS: 3,
+    },
+    _statusInfo = [
+        "Waiting...;Waiting",                                   // IDLE
+        "Calling... ;Incomming call from simulator",               // DIALED
+        "Incomming call from ;Calling simulator",                // PLACED
+        "In conversation with ;In conversation with simulator"   // INPROGRESS
+    ],
+    _data = {
+        status: _status.IDLE,
+        isInException: false,
+        isAutoAccept: false,
+        autoAcceptTimerId: null,
+        conversationStartTime: null
+    },
+    _contactMap = {
+        "861012345678": "Guest"
+    },
+    _CONTACT_KEY = "tizen1-contact",
+    _RECORDING_KEY = "tizen1-call-recording",
+    _RECORDING_PATH = "music/",
+    _record = {},
+    _conversationSeconds = 0,
+    _conversationTimer,
+    _callingEffectTimer;
+
+function _initContacts() {
+    var data = db.retrieveObject(_CONTACT_KEY),
+        contactsSelect = document.getElementById("call-local-phone-number"),
+        displayName = null, number = null, index = 0, i;
+        
+    contactsSelect.innerHTML = "";
+
+    utils.forEach(data, function (addrBook) {
+        utils.forEach(addrBook._contacts, function (contact) {
+            if (contact.name && contact.name && contact.phoneNumbers &&
+                contact.phoneNumbers.length > 0) {
+                displayName = contact.name.firstName + ' ' + contact.name.lastName;
+                number = contact.phoneNumbers[0].number;
+                _contactMap[number] = displayName;
+
+                contactsSelect.appendChild(utils.createElement("option", {
+                    "innerText": displayName + ':' + number,
+                    "value": index
+                }));
+                index++;
+            }
+        });
+    });
+
+    if (displayName === null && number === null) {
+        for (i in _contactMap) {
+            displayName = _contactMap[i];
+            number = i;
+            contactsSelect.appendChild(utils.createElement("option", {
+                "innerText": displayName + ':' + number,
+                "value": index
+            }));
+        }
+    }
+}
+
+function _initEventWatchers() {
+    event.on("DialerLaunched", function (remoteParty) {
+        var localContact = document.getElementById("call-local-phone-number");
+
+        if (_data.status !== _status.IDLE) {
+            return;
+        }
+
+        localContact.appendChild(utils.createElement("option", {
+            "innerText": remoteParty.displayName,
+            "value": remoteParty.remoteParty,
+            "selected": "selected"
+        }));
+        _localCall();
+    });
+}
+
+function _initExceptionTypes() {
+    utils.forEach(_exception, function (value, key) {
+        document.getElementById("call-exception-type").appendChild(utils.createElement("option", {
+            "innerText": value,
+            "value": key
+        }));
+    });
+}
+
+function _initRecord() {
+    var localPartString = jQuery("#call-local-phone-number option:selected").text() || "",
+        localPartStringList = localPartString.split(":"),
+        displayName;
+
+    if (localPartStringList.length > 1) {
+        displayName = localPartStringList[0];
+    }
+    else {
+        displayName = localPartString;
+    }
+
+    _record = {};
+    _record.serviceId = (new Date()).getTime() || 0;
+    _record.callParticipants = [{
+        id: localPartString + ':' + displayName,
+        displayName: displayName,
+        contactRef: null
+    }];
+    _record.forwardedFrom = null;
+    _record.startTime = new Date();
+    _record.recording = [];
+}
+
+
+function updateConvTime() {
+    var timeObj = new Date(1970, 0, 1),
+    timeString;
+
+    timeObj.setSeconds(_conversationSeconds);
+    timeString = timeObj.toTimeString().substr(0, 8);
+    jQuery("#ConvTimeString").text(timeString);
+    jQuery("#ConvTimeString2").text(timeString);
+    _conversationSeconds = _conversationSeconds + 1;
+}
+
+
+function CallingEffect() {
+    var color = jQuery("#callingString").css('color');
+    if (color === "rgb(255, 255, 255)") {
+        jQuery("#callingString").css('color', "black");
+        jQuery("#callingString2").css('color', "black");
+    }
+    else {
+        jQuery("#callingString").css('color', "white");
+        jQuery("#callingString2").css('color', "white");
+    }
+}
+
+
+function _transferStatus() {
+    var statusStringList = _statusInfo[_data.status].split(";"),
+        localPartString = jQuery("#call-local-phone-number option:selected").text() || "",
+        localPartStringList = localPartString.split(":"),
+        localNumber = localPartStringList[0],
+        localName = _contactMap[localNumber] || localNumber;
+    jQuery("#status-text").show();
+    jQuery("#remote-status-text").show();
+    jQuery("#call-status").show();
+    jQuery("#remote-call-status").show();
+    jQuery("#remotePartyName").html(localName);
+    jQuery("#call-local-call").show();
+    window.clearInterval(_callingEffectTimer);
+
+    switch (_data.status) {
+    case _status.DIALED:      // local call
+        jQuery("#call-remote-text").html("Accept");
+        jQuery("#end-remote-text").html("Reject");
+        jQuery("#call-status").html("<span style='font-size: 22px;'>" + localName + "</span><br>" + 
+                        "<span id='callingString' style='font-size: 14px;'>&nbsp;" + statusStringList[0] + 
+                        "</span><br><br><br><button id='call-local-end-d' class='ui-corner-all' style='padding:2px;" +
+                        " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
+        jQuery("#call-local-end-d").bind("click", _localEnd);
+        jQuery("#remote-call-status").html("<span style='font-size: 20px;'>Simulator Bot</span><br>" + 
+                        "<span id='callingString2' style='font-size: 12px;'>&nbsp;Incoming call...</span>" +
+                        "<br><br><br><button id='call-remote-decline-d' class='ui-corner-all' style='padding:2px;" +
+                        " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:48%;'>Decline</button>&nbsp;&nbsp;" +
+                        "<button id='call-remote-answer-d' class='ui-corner-all' style='padding:2px; border-width:1px; background-color:green; color:white; font-size:14px; font-weight:bold; width:48%;'>Answer</button>");
+        jQuery("#call-remote-answer-d").bind("click", _remoteCall);
+        jQuery("#call-remote-decline-d").bind("click", _remoteEnd);
+        _callingEffectTimer = window.setInterval(CallingEffect, 800);
+        break;
+    case _status.PLACED:      // Remote Call
+        jQuery("#call-local-text").html("Accept");
+        jQuery("#end-local-text").html("Reject");
+        jQuery("#call-status").html(statusStringList[0] + localName);
+        jQuery("#remote-call-status").html(statusStringList[1]);
+        jQuery("#remote-call-status").html("<span style='font-size: 22px;'>Simulator Bot</span><br>" + 
+                        "<span id='callingString' style='font-size: 14px;'>&nbsp;Calling..." + 
+                        "</span><br><br><br><button id='call-remote-end-d' class='ui-corner-all' style='padding:2px;" +
+                        " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
+        jQuery("#call-remote-end-d").bind("click", _remoteEnd);
+        jQuery("#call-status").html("<span style='font-size: 22px;'>" + localName + "</span><br>" + 
+                        "<span id='callingString2' style='font-size: 14px;'>&nbsp;Incoming call...</span>" +
+                        "<br><br><br><button id='call-local-decline-d' class='ui-corner-all' style='padding:2px;" +
+                        " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:48%;'>Decline</button>&nbsp;&nbsp;" +
+                        "<button id='call-local-answer-d' class='ui-corner-all' style='padding:2px; border-width:1px;" +
+                        " background-color:green; color:white; font-size:14px; font-weight:bold; width:48%;'>Answer</button>");
+        jQuery("#call-local-answer-d").bind("click", _localCall);
+        jQuery("#call-local-decline-d").bind("click", _localEnd);
+        _callingEffectTimer = window.setInterval(CallingEffect, 800);
+        break;
+    case _status.INPROGRESS:
+        jQuery("#call-status").html("<span style='font-size: 22px;'>" + localName + "</span><br>" + 
+                        "<span id='ConvTimeString' style='font-size: 14px;'>" + "00:00:00" + 
+                        "</span><br><br><br><button id='call-local-end-d-c' class='ui-corner-all' style='padding:2px;" +
+                        " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
+        jQuery("#remote-call-status").html("<span style='font-size: 22px;'>Simulator Robot</span><br>" + 
+                        "<span id='ConvTimeString2' style='font-size: 14px;'>" + "00:00:00" + 
+                        "</span><br><br><br><button id='call-remote-end-d-c' class='ui-corner-all' style='padding:2px;" +
+                        " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
+        jQuery("#call-local-end-d-c").bind("click", _localEnd);
+        jQuery("#call-remote-end-d-c").bind("click", _remoteEnd);
+        _conversationTimer = window.setInterval(updateConvTime, 1000);
+        jQuery("#call-remote-text").html("Call");
+        jQuery("#end-remote-text").html("End");
+        jQuery("#call-local-text").html("Call");
+        jQuery("#end-local-text").html("End");
+        break;
+    default:
+        jQuery("#call-status").html(statusStringList[0]);
+        jQuery("#call-status").html("default");
+        jQuery("#remote-call-status").html(statusStringList[1]);
+        jQuery("#remote-call-status").html("default");
+        jQuery("#call-remote-text").html("Call");
+        jQuery("#end-remote-text").html("End");
+        jQuery("#call-local-text").html("Call");
+        jQuery("#end-local-text").html("End");
+        return;
+    }
+}
+
+function _startCall() {
+    _data.conversationStartTime = new Date();
+    event.trigger("CallInProgress", [true]);
+    _data.status = _status.INPROGRESS;
+    //_transferStatus();
+}
+
+function _endCall(callEndReason) {
+    if (_data.autoAcceptTimerId) {
+        var path = _RECORDING_PATH + _record.serviceId + ".mp3";
+
+        _record.recording.push(path);
+        db.saveObject(_RECORDING_KEY, path);
+
+        clearTimeout(_data.autoAcceptTimerId);
+        _data.autoAcceptTimerId = null;
+    }
+
+    _record.duration = _data.conversationStartTime ? ((new Date()) - _data.conversationStartTime) : 0;
+    _data.conversationStartTime = null;
+    
+    _record.endReason = callEndReason;
+
+    if (_data.status === _status.PLACED) {
+        _record.direction = "missed-new";
+    }
+
+    event.trigger("CallRecorded", [_record]);
+    event.trigger("CallInProgress", [false]);
+
+    _data.status = _status.IDLE;
+    _transferStatus();
+    _record = {};
+
+    _conversationSeconds = 0;
+    window.clearInterval(_conversationTimer);
+    jQuery("#call-status").hide();
+    jQuery("#remote-call-status").hide();
+
+    jQuery("#status-text").hide();
+    jQuery("#remote-status-text").hide();
+}
+
+function _localCall() {
+    if (_data.isInException) {
+        return;
+    }
+
+    switch (_data.status) {
+    case _status.IDLE:    //local call
+        _data.status = _status.DIALED;
+        _initRecord();
+        _record.direction = "dialed";
+        break;
+    case _status.PLACED:
+        _data.status = _status.INPROGRESS;
+        _record.direction = "received";
+        if (_data.autoAcceptTimerId) {
+            clearTimeout(_data.autoAcceptTimerId);
+            _data.autoAcceptTimerId = null;
+        }
+        _startCall();
+        break;
+    default:
+        return;
+    }
+
+    _transferStatus();
+
+    if (_data.isInException) {
+        _endCall(document.getElementById("call-exception-type").value);
+    }
+}
+
+function _localEnd() {
+    switch (_data.status) {
+    case _status.DIALED:     // Local Cancel
+    case _status.INPROGRESS: // Local End
+        _endCall("local");
+        break;
+    case _status.PLACED:
+        _record.direction = "missed-new";
+        _endCall("local");
+        break;
+    default:
+        return;
+    }
+}
+
+function _remoteCall() {
+    if (_data.isInException) {
+        return;
+    }
+
+    switch (_data.status) {
+    case _status.IDLE:      // Remote Call
+        _data.status = _status.PLACED; 
+        _initRecord();
+        if (_data.isAutoAccept) {
+            _data.autoAcceptTimerId = setTimeout(_localCall, 2000);
+        }
+        break;
+    case _status.DIALED:    // Remote Answer
+        _startCall();
+        break;
+    default:
+        return;
+    }
+
+    _transferStatus();
+
+    if (_data.isInException) {
+        _endCall(document.getElementById("call-exception-type").value);
+    }
+}
+
+function _remoteEnd() {
+    switch (_data.status) {
+    case _status.DIALED:     // Remote Reject
+        _endCall("rejected");
+        break;
+    case _status.INPROGRESS: // Remote End
+        _endCall("remote");
+        break;
+    case _status.PLACED:    // Remote Cancel
+        _record.direction = "missed-new";
+        _endCall("remote");
+        break;
+    default:
+        return;
+    }
+}
+
+function _leaveMessage() {
+    if (!this.checked && _data.autoAcceptTimerId) {
+        clearTimeout(_data.autoAcceptTimerId);
+        _data.autoAcceptTimerId = null;
+    }
+    _data.isAutoAccept = this.checked;
+}
+
+function _exceptionStatus() {
+    _data.isInException = this.checked;
+    if (_data.isInException && (_data.status !== _status.IDLE)) {
+        if (_data.status === _status.RECEIVED) {   // Remote Cancel
+            _record.direction = "missed-new";
+            _record.duration = 0;
+        }
+        _endCall(document.getElementById("call-exception-type").value);
+    }
+}
+
+
+function _updateRemotePartyName() {
+    jQuery("#remotePartyName").text(jQuery("#call-local-phone-number option:selected").text());
+}
+
+
+module.exports = {
+    panel: {
+        domId: "call-container",
+        collapsed: true,
+        pane: "left",
+        titleName: "Call",
+        display: true
+    },
+    initialize: function () {
+        jQuery("#call-local-call").bind("click", _localCall);
+        jQuery("#call-local-end").bind("click", _localEnd);
+        jQuery("#call-remote-call").bind("click", _remoteCall);
+        jQuery("#call-remote-end").bind("click", _remoteEnd);
+        jQuery("#recording-status").bind("click", _leaveMessage);
+        jQuery("#call-exception-status").bind("click", _exceptionStatus);
+        jQuery("#call-exception-type").bind("click", null);
+
+        _initEventWatchers();
+        _initContacts();
+        jQuery("#remotePartyName").text(jQuery("#call-local-phone-number option:selected").text());
+        jQuery("#call-local-phone-number").bind("change", _updateRemotePartyName);
+        _initExceptionTypes();
+    }
+};
+
+});
+require.define('ripple/ui/plugins/settings-menu', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    constants = require('ripple/constants'),
+    _platform = require('ripple/platform'),
+    db = require('ripple/db'),
+    _applicationStateId
+    ;
+
+
+function reload() {
+    location.reload();
+}
+
+function _showSettingMenu() {
+    var contentTable = "",
+    settings = [],
+    _applicationState = [],
+    _applicationStateTmp = [],
+    i = 0;
+
+    if ($("#settings-menu-popup").is(":visible")) {
+        $("#settings-menu-popup").hide("slide", {direction: "up"},"slow");
+        $("#overlayBackground").hide("fade", "slow");
+        return;
+    }
+
+    _applicationStateId = constants.COMMON.APPLICATION_STATE +
+        ((db.retrieveObject(constants.PLATFORM.SAVED_KEY) || constants.PLATFORM.DEFAULT)).name;
+
+    _applicationStateTmp = db.retrieveObject(_applicationStateId) || [];
+
+    utils.forEach(_applicationStateTmp, function (obj) {
+        if (obj.display)
+            _applicationState.push(obj);
+    });
+
+    utils.forEach(_applicationStateTmp, function (obj) {
+        if (!obj.display)
+            _applicationState.push(obj);
+    });
+
+    $("#settings-menu-content-panel-table").remove();
+
+    contentTable = '<table id="settings-menu-content-panel-table" class="settings-menu-content-table">';
+    utils.forEach(_applicationState, function (obj) {
+        var checked = obj.display ? 'checked="yes"':"";
+        contentTable += '<tr><td><input name="panel-display-setting" type="checkbox" class="settings-menu-checkbox "'+
+                        checked +'></input>'+
+                        obj.titleName+'</td></tr>\n';
+    });
+    contentTable += "</table>";
+
+    $("#settings-menu-container-div").append(contentTable);
+    $("#settings-menu-popup").css( "top" , 50  );
+    $("#settings-menu-popup").css( "left" , $(window).width() - 340  );
+
+    $("#overlayBackground").css("width", $(window).width());
+    $("#overlayBackground").css("height", $(window).height());
+    $("#overlayBackground").show("fade", "slow");
+    $("#settings-menu-popup").show("slide", {direction: "up"}, "slow");
+
+    $("#settings-menu-save-btn").unbind('click');
+    $("#settings-menu-save-btn").bind("click", function (event) {
+        $("input[name='panel-display-setting']").each(function (i, a) {
+            settings.push(a.checked);
+        });
+
+        utils.forEach(_applicationState, function (obj) {
+            if (!settings[i])
+                obj.collapsed = true;
+            obj.display = settings[i];
+            i++
+        }, this);
+  
+        db.saveObject(_applicationStateId, _applicationState);
+        _applicationStateTmp = db.retrieveObject(_applicationStateId) || [];
+
+        $("#settings-menu-popup").hide("slide", {direction: "up"},"slow");
+        $("#overlayBackground").hide("fade", "slow");
+        setTimeout(reload, 500);
+    });
+
+    $(".settings-menu-content-table td").unbind('click');
+    $(".settings-menu-content-table td").bind("click", function (event) {
+        var checkbox;
+        if (($(event.target).children().length == 0))
+            return;
+        else
+            checkbox = $(event.target).children()
+        
+        if (checkbox.is(':checked')) {
+            checkbox.prop('checked', false);
+        }
+        else
+            checkbox.prop('checked', true);
+    });
+
+    $("#settings-menu-close-btn").unbind('click');
+    $("#settings-menu-close-btn").bind("click", function (event) {
+       if ($("#settings-menu-popup").is(":visible")) {
+            $("#settings-menu-popup").hide("slide", {direction: "up"},"slow");
+            $("#overlayBackground").hide("fade", "slow");
+            return;
+        }
+    });
+
+    $(window).unbind('resize');
+    $(window).bind('resize', function() {
+        $("#settings-menu-popup").css( "top" , 50);
+        $("#settings-menu-popup").css( "left" , $(window).width() - 340);
+        $("#overlayBackground").css("width", $(window).width());
+        $("#overlayBackground").css("height", $(window).height());
+    });
+}
+
+module.exports = {
+    initialize: function () {
+         $("#options-button-setting-menu").bind("click", function (event) {
+            _showSettingMenu();
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/sensorSettings', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var constants = require('ripple/constants'),
+    sensorSettings = require('ripple/sensorSettings'),
+    utils = require('ripple/utils'),
+    exception = require('ripple/exception'),
+    platform = require('ripple/platform'),
+    _CONST = {
+        "CONTENT_CONTAINER_ID": "sensorsettings-content-container",
+        "UKNOWN_CONTROL_MESSAGE": "Unknown sensor control type"
+    },
+    _contentContainer,
+    _CONTAINER_ID = _CONST.CONTENT_CONTAINER_ID;
+
+function _appendSettingNode(labelNode, inputNode, label) {
+    var frag = document.createDocumentFragment(),
+        rowNode = frag.appendChild(utils.createElement("tr")),
+        tempTdNode;
+
+    rowNode.appendChild(utils.createElement("td"))
+           .appendChild(labelNode);
+
+    tempTdNode = rowNode.appendChild(utils.createElement("td"));
+
+    if (label) {
+        tempTdNode.appendChild(label);
+    }
+
+    tempTdNode.appendChild(inputNode);
+
+    return frag;
+}
+
+function _buildDOMNode(setting, settingType, key) {
+    var settingsNode, tagName, jNode,
+        fullKey = settingType + "." + key,
+        savedSetting = sensorSettings.retrieve(fullKey),
+        // TODO: move this into Utils (isSet method)
+        currentSetting = (savedSetting || savedSetting === false || savedSetting === "" || savedSetting === 0) ? savedSetting : setting.control.value,
+        domNode,
+        domNodeLabel = null;
+
+    switch (setting.control.type) {
+    case "text":
+    case "number":
+    case "range":
+    case "checkbox":
+        tagName = "input";
+        break;
+    case "textarea":
+        tagName = "textarea";
+        break;
+    case "select":
+        tagName = "select";
+        break;
+    default:
+        exception.raise(exception.types.Application, _CONST.UKNOWN_CONTROL_MESSAGE);
+    }
+
+    settingsNode = utils.createElement(tagName, setting.control.type === "select" ? null : setting.control);
+
+    // TODO: this should really be part of utils.createControl? add element of type "range" with label?
+    if (setting.control.type === "range") {
+        domNodeLabel = utils.createElement("label", {
+            "class": constants.UI.LEFT_RANGE_LABEL_CLASS
+        });
+    }
+
+    domNode = _appendSettingNode(utils.createElement("span", {"innerText": setting.name, "class": constants.UI.TEXT_LABEL_CLASS}), settingsNode, domNodeLabel);
+
+    jNode = jQuery(settingsNode);
+    jNode.addClass(constants.UI.JQUERY_UI_INPUT_CLASSES);
+
+    switch (setting.control.type) {
+    case "checkbox":
+        jNode.bind("click", function () {
+            var checked = this.checked ? true : false;
+            sensorSettings.persist(fullKey, checked);
+            if (typeof setting.callback === "function") {
+                setting.callback(checked);
+            }
+        });
+
+        if (currentSetting === true) {
+            jNode.attr("checked", "checked");
+        }
+
+        break;
+
+    case "text":
+    case "textarea":
+    case "number":
+        jNode.val(currentSetting);
+        utils.bindAutoSaveEvent(jNode, function () {
+            sensorSettings.persist(fullKey, jNode.val());
+            if (typeof setting.callback === "function") {
+                setting.callback(jNode.val());
+            }
+        });
+        break;
+
+    case "select":
+    case "range":
+        if (setting.control.type === "select") {
+            utils.forEach(setting.options,  function (value, option) {
+                jNode.append(utils.createElement("option", {
+                    "value": option,
+                    "innerText": value
+                }));
+            });
+        }
+        else {
+            if (domNodeLabel) {
+                domNodeLabel.innerText = currentSetting;
+            }
+        }
+
+        jNode.val(currentSetting)
+             .bind("change", function () {
+                if (setting.control.type === "range" && domNodeLabel) {
+                    domNodeLabel.innerText = jQuery(this).val();
+                }
+                sensorSettings.persist(fullKey, jQuery(this).val());
+
+                if (typeof setting.callback === "function") {
+                    setting.callback(jQuery(this).val());
+                }
+            }
+        );
+    }
+
+    // TODO: Brent, do in DeviceSettings on load instead?
+    if (currentSetting !== setting.control.value) {
+        sensorSettings.register(fullKey, currentSetting);
+    }
+
+    return domNode;
+}
+
+// goes through current platforms sensor settings
+// adds nodes to panel and binds respective events
+// talks to SensorSettings for persistence
+module.exports = {
+    panel: {
+        domId: "sensors-panel-container",
+        collapsed: true,
+        pane: "right",
+        titleName: "Sensors",
+        display: true
+    },
+    initialize: function () {
+        var settings;
+
+        _contentContainer = document.getElementById(_CONTAINER_ID);
+
+        settings = platform.current().sensor;
+
+        utils.forEach(settings, function (settingSection, settingType) {
+
+            var currentTableNode, flag = false;
+            
+            utils.forEach(settingSection, function (setting, key) {
+                if (typeof setting === "object") {
+                    flag = true;
+                    return;
+                }
+            });
+
+            if (flag) {
+                _contentContainer.appendChild(utils.createElement("h3", { "innerText": settingType }));
+            }
+
+            currentTableNode = utils.createElement("table", {
+                "class": constants.UI.PANEL_TABLE_CLASS
+            });
+
+            _contentContainer.appendChild(currentTableNode);
+
+            utils.forEach(settingSection, function (setting, key) {
+                if (typeof setting === "object") {
+                    currentTableNode.appendChild(_buildDOMNode(setting, settingType, key));
+                }
+
+            });
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/push', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    PUSH_OPTIONS = constants.PUSH.OPTIONS;
+
+function _updatePushPanel(ports) {
+    var portsSelect = document.getElementById("port-select"),
+        currentPort = portsSelect.value;
+
+    portsSelect.innerHTML = "";
+
+    ports.forEach(function (port) {
+        portsSelect.appendChild(utils.createElement("option", {
+            innerText: port,
+            value: port,
+            selected: currentPort === port
+        }));
+    });
+}
+
+module.exports = {
+    panel: {
+        domId: "push-container",
+        collapsed: true,
+        pane: "left"
+    },
+    initialize: function () {
+        event.on("PushListenersChanged", function (listeners) {
+            _updatePushPanel(listeners);
+            jQuery("#port-select").effect("highlight", {color: "#62B4C8"}, 1000);
+        });
+
+        _updatePushPanel([]);
+
+        document.getElementById("push-send")
+            .addEventListener("click", function () {
+                var port = document.getElementById("port-select").value,
+                    text = document.getElementById(PUSH_OPTIONS.PAYLOAD).value,
+                    pushData = {
+                        headerField: ["21f39092"],
+                        requestURI: "/",
+                        source: "ripple",
+                        isChannelEncrypted: false,
+                        payload: text
+                    };
+
+                event.trigger("Push", [pushData, port], true);
+            }, false);
+
+        utils.bindAutoSaveEvent(jQuery("#" + PUSH_OPTIONS.PAYLOAD), function () {
+            db.save(PUSH_OPTIONS.PAYLOAD, document.getElementById(PUSH_OPTIONS.PAYLOAD).value);
+        });
+
+        document.getElementById(PUSH_OPTIONS.PAYLOAD).value = db.retrieve(PUSH_OPTIONS.PAYLOAD) || "My payload data";
+    }
+};
+
+});
+require.define('ripple/ui/plugins/application', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    _data = {
+        DB_APPLICATION_KEY : "tizen1-db-application",
+        programs : []
+    },
+    _cleanInputs,
+    _apps;
+
+function _get() {
+    _apps = [
+        {
+        appId : "ID001",
+        appInfo : {id : "ID001", name : "Tizen App1", iconPath : "app1.png", version : "1.0", show : true},
+        },
+        {
+        appId : "ID002",
+        appInfo : {id : "ID002", name : "Tizen App2", iconPath : "app2.png", version : "2.0", show : true},
+        },
+    ];
+    _data.programs = db.retrieveObject(_data.DB_APPLICATION_KEY) || _apps;
+    _save();
+}
+
+function _save() {
+    db.saveObject(_data.DB_APPLICATION_KEY, _data.programs);
+}
+
+function _loadPrograms() {
+    var installed = document.getElementById("application-installed"), node, i;
+    installed.innerHTML = "";
+    for (i in _data.programs) {
+        node = utils.createElement("option", {
+            "innerText": _data.programs[i].appInfo.name,
+            "value": _data.programs[i].appId
+        });
+        installed.appendChild(node);
+    }
+    _cleanInputs();
+}
+
+function _displayInfo(text) {
+    var html = "<b>" + text + "</b>";
+    document.getElementById("application-error").innerHTML = html;
+}
+
+function _programChanged(status, param) {
+    event.trigger("programChanged", [status, param]);
+}
+
+function _cleanInputs() {
+    document.getElementById("application-operation").value = "";
+    document.getElementById("application-uri").value = "";
+    document.getElementById("application-mime").value = "";
+    document.getElementById("application-id").value = "";
+    document.getElementById("application-name").value = "";
+    document.getElementById("application-iconPath").value = "";
+    document.getElementById("application-version").value = "";
+    document.getElementsByName("application-show")[0].checked = false;
+    document.getElementsByName("application-show")[1].checked = false;
+}
+
+function _install() {
+    var operation, uri, mime, id, name, iconPath, version, show, i, app;
+
+    operation = document.getElementById("application-operation").value;
+    uri       = document.getElementById("application-uri").value;
+    mime      = document.getElementById("application-mime").value;
+    id        = document.getElementById("application-id").value;
+    name      = document.getElementById("application-name").value;
+    iconPath  = document.getElementById("application-iconPath").value;
+    version   = document.getElementById("application-version").value;
+    show      = document.getElementsByName("application-show")[0].checked;
+
+    if (_data.programs.length !== 0) {
+        for (i in _data.programs) {
+            if (id === _data.programs[i].appId) {
+                return;
+            }
+        }
+    }
+    app = {
+        appId : id,
+        appInfo : {id : id, name : name, iconPath : iconPath, version : version, show : show},
+        appServices : [{operation : operation, uri : uri, mime : mime}]
+    };
+    _data.programs.push(app);
+    _save();
+    _programChanged("installed", app.appInfo);
+    _loadPrograms();
+}
+
+function _update() {
+    var i, id, name, version, show, iconPath, operation, uri, mime, length;
+
+    length   = _data.programs.length;
+    id       = document.getElementById("application-id").value;
+    name     = document.getElementById("application-name").value;
+    iconPath = document.getElementById("application-iconPath").value;
+    version  = document.getElementById("application-version").value;
+    show     = document.getElementsByName("application-show")[0].checked;
+    operation = document.getElementById("application-operation").value;
+    uri       = document.getElementById("application-uri").value;
+    mime      = document.getElementById("application-mime").value;
+
+    if (length === 0)
+        return;
+
+    for (i in _data.programs) {
+        if (_data.programs[i].appId === id) {
+            _data.programs[i].appInfo = {id : id, name : name, iconPath : iconPath, version : version, show : show};
+            _data.programs[i].appServices = [{operation : operation, uri : uri, mime : mime}];
+            _save();
+            _programChanged("updated", _data.programs[i].appInfo);
+            _loadPrograms();
+            break;
+        }
+    }
+}
+
+function _uninstall() {
+    var i, id = null;
+    id = document.getElementById("application-id").value;
+    if (id) {
+        for (i in _data.programs) {
+            if (_data.programs[i].appId === id) {
+                _data.programs.splice(i, 1);
+                _save();
+                _programChanged("uninstalled", id);
+                _loadPrograms();
+            }
+        }
+    }
+}
+
+function _showAppDetail(id) {
+    var i;
+    for (i in _data.programs) {
+        if (id === _data.programs[i].appId) {
+            jQuery("#application-id").val(_data.programs[i].appInfo.id);
+            jQuery("#application-name").val(_data.programs[i].appInfo.name);
+            jQuery("#application-iconPath").val(_data.programs[i].appInfo.iconPath);
+            jQuery("#application-version").val(_data.programs[i].appInfo.version);
+            if (_data.programs[i].appInfo.show) {
+                document.getElementsByName("application-show")[0].checked = true;
+                document.getElementsByName("application-show")[1].checked = false;
+            } else {
+                document.getElementsByName("application-show")[0].checked = false;
+                document.getElementsByName("application-show")[1].checked = true;
+            }
+            jQuery("#application-operation").val(_data.programs[i].appServices[0].operation);
+            jQuery("#application-uri").val(_data.programs[i].appServices[0].uri);
+            jQuery("#application-mime").val(_data.programs[i].appServices[0].mime);
+        }
+    }
+}
+
+function _changeAppData() {
+    var id = jQuery("#application-installed").val();
+    _showAppDetail(id);
+}
+
+event.on("appServiceReplied", function (data) {
+    _displayInfo("The application has been launched successfully");
+});
+
+event.on("appsInit", function (data) {
+    data.applications = _data.programs;
+});
+
+module.exports = {
+    panel: {
+        domId: "application-container",
+        collapsed: true,
+        pane: "left",
+        titleName: "Program Manager",
+        display: true
+    },
+    initialize: function () {
+        _get();
+        _loadPrograms();
+
+        document.getElementById("application-install").addEventListener("click", _install, false);
+        document.getElementById("application-update").addEventListener("click", _update, false);
+        document.getElementById("application-uninstall").addEventListener("click", _uninstall, false);
+        jQuery("#application-installed").bind("focus", function () {
+            _changeAppData();
+        });
+        jQuery("#application-installed").bind("change", function () {
+            _changeAppData();
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/videoPlayer', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    event = require('ripple/event');
+
+module.exports = {
+    initialize: function () {
+        var videoObj,
+            videoProgress = document.getElementById(constants.COMMON.MULTIMEDIA_VIDEO_PROGRESS_ID);
+
+        event.on("MultimediaAppVideoPlayerCreated", function (videoDOMObj) {
+            videoObj = videoDOMObj;
+
+            videoObj.addEventListener("timeupdate", function () {
+                var s = parseInt(videoObj.currentTime % 60, 10),
+                    m = parseInt((videoObj.currentTime / 60) % 60, 10);
+
+                videoProgress.innerText = ((m > 9) ? m  : "0" + m) + ':' + ((s > 9) ? s  : "0" + s);
+            }, false);
+        });
+
+        event.on("MultimediaVolumeChanged", function (volume) {
+            if (videoObj) {
+                videoObj.volume = parseFloat(volume / 10);
+            }
+        });
+
+        event.on("MultimediaVideoStateChanged", function (state) {
+            document.getElementById(constants.COMMON.MULTIMEDIA_VIDEO_STATE_FIELD_ID).innerText = state;
+            document.getElementById(constants.COMMON.MULTIMEDIA_VIDEO_FILE_FIELD_ID).innerText = videoObj.getAttribute("src");
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/touchEvent', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var event = require('ripple/event'),
+    db = require('ripple/db'),
+    constants = require('ripple/constants'),
+    colors  = ["red", "green", "magenta", "blue", "yellow"],
+    Point,
+    intervalId,
+    moveEvents  = {},
+    currentIndex = 0,
+    enlargeRatio = 4;
+
+function _exec(operation) {
+    var canvas = document.getElementById(constants.TOUCHEVENT.CANVAS),
+        cxt = canvas.getContext("2d"),
+        altKey = document.getElementById(constants.TOUCHEVENT.ALTKEY),
+        metaKey = document.getElementById(constants.TOUCHEVENT.METAKEY),
+        ctrlKey = document.getElementById(constants.TOUCHEVENT.CTRLKEY),
+        shiftKey = document.getElementById(constants.TOUCHEVENT.SHIFTKEY),
+        key, eventType;
+
+    if (operation === "start") {
+        altKey.disabled = 'disabled';
+        metaKey.disabled = 'disabled';
+        ctrlKey.disabled = 'disabled';
+        shiftKey.disabled = 'disabled';
+        clearInterval(intervalId);
+        currentIndex = 0;
+        eventType = "touchEvent";
+    } else if (operation === "cancel") {
+        altKey.disabled = '';
+        metaKey.disabled = '';
+        ctrlKey.disabled = '';
+        shiftKey.disabled = '';
+        altKey.checked = false;
+        metaKey.checked = false;
+        ctrlKey.checked = false;
+        shiftKey.checked = false;
+        cxt.clearRect(0, 0, canvas.width, canvas.height);
+        moveEvents = {};
+        eventType = "touchCancel";
+    }
+
+    event.trigger(eventType, [{
+        data : moveEvents,
+        keys : [altKey.checked, metaKey.checked, ctrlKey.checked, shiftKey.checked]
+    }]);
+}
+
+Point = function (x, y, color, isDragging) {
+    var _self = {};
+
+    _self.x = x;
+    _self.y = y;
+    _self.color = color;
+    _self.isDragging = isDragging;
+
+    return _self;
+};
+
+module.exports = {
+    panel: {
+        domId: "touchEvent-container",
+        collapsed: true,
+        pane: "left",
+        titleName: "Touch Event",
+        display: true
+    },
+
+    initialize: function () {
+        var deviceInfo = require('ripple/devices').getCurrentDevice(),
+            canvas = document.getElementById(constants.TOUCHEVENT.CANVAS),
+            button = document.getElementById(constants.TOUCHEVENT.OPTION),
+            cxt = canvas.getContext("2d"),
+            points = [],
+            paint = false,
+            currentPoint = {};
+
+        function drawPoints() {
+            var key, index, points = [], point;
+
+            for (key in moveEvents) {
+                points = moveEvents[key];
+                cxt.fillStyle = colors[key];
+
+                for (index = 0; index < points.length; index++) {
+                    point = points[index];
+                    cxt.beginPath();
+                    cxt.arc(point.offsetX, point.offsetY, 5, 0, 2 * Math.PI, 1);
+                    cxt.fill();
+                }
+            }
+        }
+
+        function endDraw(event) {
+            if (paint) {
+                paint = false;
+                clearInterval(intervalId);
+                moveEvents[currentIndex].push(event);
+                drawPoints();
+
+                currentIndex++;
+                if (currentIndex === 5)
+                    currentIndex = 0;
+            }
+        }
+
+        canvas.addEventListener("mousedown", function (event) {
+            if (button.value === "Touch Cancel") {
+                button.value = "Touch Start";
+                _exec("cancel");
+            }
+            moveEvents[currentIndex] = [];
+            currentPoint = event;
+            moveEvents[currentIndex].push(event);
+            paint = true;
+            drawPoints();
+            intervalId = setInterval(function () {
+                moveEvents[currentIndex].push(currentPoint);
+            }, 100);
+        });
+
+        canvas.addEventListener("mousemove", function (event) {
+            if (paint) {
+                currentPoint = event;
+                drawPoints();
+            }
+        });
+
+        canvas.addEventListener("mouseup", endDraw);
+        canvas.addEventListener("mouseout", endDraw);
+        canvas.addEventListener("mouseleave", endDraw);
+
+        document.getElementById(constants.TOUCHEVENT.OPTION).addEventListener("click", function () {
+            if (!moveEvents[0])
+                return;
+
+            if (this.value === "Touch Start") {
+                this.value = "Touch Cancel";
+                _exec("start");
+            } else if (this.value === "Touch Cancel") {
+                this.value = "Touch Start";
+                _exec("cancel");
+            }
+        }, false);
+
+        canvas.width = deviceInfo.screen.width / enlargeRatio;
+        canvas.height = deviceInfo.screen.height / enlargeRatio;
+    }
+};
+
+});
+require.define('ripple/ui/plugins/tooltips', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// Class: UI.Tooltips
+// Purpose: build tooltips for UI
+// See here for Tooltip Options
+// http://jquery.bassistance.de/tooltip/demo/
+var utils = require('ripple/utils'),
+    tooltip = require('ripple/ui/plugins/tooltip'),
+    constants = require('ripple/constants'),
+    db = require('ripple/db'),
+    utils = require('ripple/utils');
+
+function _updateButtonText() {
+    document.querySelector("#settings-toggletooltips > span")
+            .innerHTML = "Turn " + (tooltip.isOff() ? "On" : "Off");
+}
+
+module.exports = {
+    initialize: function () {
+        var saved = db.retrieve(constants.SETTINGS.TOOLTIPS_KEY);
+
+        // blarg, tooltips are always enabled so if its saved to false disable it
+        if (!tooltip.isOff() && (saved === "false" || saved === false)) {
+            tooltip.toggle();
+        }
+
+        _updateButtonText();
+
+        jQuery(constants.SETTINGS.TOOLTIPS_TOGGLE_DIV).click(function () {
+            db.save(constants.SETTINGS.TOOLTIPS_KEY, !tooltip.toggle());
+            _updateButtonText();
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/layout', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    db = require('ripple/db'),
+    resizer = require('ripple/resizer'),
+    devices = require('ripple/devices'),
+    event = require('ripple/event');
+
+function _initializeLayout(prev, baton) {
+    var layout = db.retrieve(constants.ENCAPSULATOR.LAYOUT),
+        layoutLandscape = document.getElementById(constants.COMMON.ORIENTATION_SELECT_LANDSCAPE_ID),
+        layoutPortrait = document.getElementById(constants.COMMON.ORIENTATION_SELECT_PORTRAIT_ID),
+        currentDevice = devices.getCurrentDevice(),
+        defaultOrientation =  currentDevice ? currentDevice.defaultOrientation : null,
+        layoutTypeChanged = false;
+
+    jQuery("#" + constants.COMMON.ORIENTATION_SELECT_LANDSCAPE_ID).bind("click", function () {
+        resizer.changeLayoutType(constants.ENCAPSULATOR.DISPLAY_LAYOUT.LANDSCAPE);
+        event.trigger("LayoutChanged", [constants.ENCAPSULATOR.DISPLAY_LAYOUT.LANDSCAPE], true);
+        layoutLandscape.setAttribute("class", "layout-selected");
+        layoutPortrait.setAttribute("class", "layout-not-selected");
+    });
+
+    jQuery("#" + constants.COMMON.ORIENTATION_SELECT_PORTRAIT_ID).bind("click", function () {
+        resizer.changeLayoutType(constants.ENCAPSULATOR.DISPLAY_LAYOUT.PORTRAIT);
+        event.trigger("LayoutChanged", [constants.ENCAPSULATOR.DISPLAY_LAYOUT.PORTRAIT], true);
+        layoutLandscape.setAttribute("class", "layout-not-selected");
+        layoutPortrait.setAttribute("class", "layout-selected");
+    });
+
+    jQuery("#" + constants.COMMON.MENU_BUTTON).bind("click", function () {
+        event.trigger("HardwareKey", [1]);
+    });
+
+    jQuery("#" + constants.COMMON.BACK_BUTTON).bind("click", function () {
+        event.trigger("HardwareKey", [0]);
+    });
+
+    if (!layout) {
+        layout = defaultOrientation || constants.ENCAPSULATOR.DISPLAY_LAYOUT.PORTRAIT;
+        layoutTypeChanged = true;
+        resizer.changeLayoutType(layout);
+    }
+
+    //Hide the orientation buttons that we don't need for this device
+    if (!currentDevice.viewPort.landscape) {
+        layoutLandscape.setAttribute("style", "display:none");
+    }
+
+    if (!currentDevice.viewPort.portrait) {
+        layoutPortrait.setAttribute("style", "display:none");
+    }
+
+    if (layout && layout === constants.ENCAPSULATOR.DISPLAY_LAYOUT.PORTRAIT) {
+        layoutLandscape.setAttribute("class", "layout-not-selected");
+        layoutPortrait.setAttribute("class", "layout-selected");
+    }
+    else if (layout && layout === constants.ENCAPSULATOR.DISPLAY_LAYOUT.LANDSCAPE) {
+        layoutLandscape.setAttribute("class", "layout-selected");
+        layoutPortrait.setAttribute("class", "layout-not-selected");
+    }
+
+    if (!layoutTypeChanged) {
+        resizer.resize(currentDevice);
+    }
+}
+
+module.exports = {
+    initialize: _initializeLayout
+};
+
+});
+require.define('ripple/ui/plugins/bluetooth', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    _remoteDevice = {},
+    _remoteDevs = [],
+    _isBonding;
+
+function _getRemoteDevs() {
+    var remoteDevs1,
+        remoteDevs2,
+        remoteDevs3,
+        remoteDevs4,
+        remoteDevs5,
+        remoteDevs6,
+        deviceClass = {
+            major : 0x02,
+            minor : 0x03,
+            services : [0x0010, 0x0100]
+        };
+
+    _remoteDevice = {
+        name : "remoteBluetooth",
+        address : "14:22:33:44:95:68",
+        deviceClass : deviceClass,
+        isBonded : false,
+        isTrusted : true,
+        isConnected : true,
+        uuids : ["5bce9431-6d25-32ab-afe0-2ecdra30860"]
+    };
+    remoteDevs1 = {
+        name : "remoteDevs1",
+        address : "11:22:33:44:55:66",
+        deviceClass : deviceClass,
+        isBonded : false,
+        isTrusted : true,
+        isConnected : true,
+        uuids : ["5bce9431-6c75-32ab-afe0-2ec108a30860"]
+    };
+    remoteDevs2 = {
+        name : "remoteDevs2",
+        address : "11:27:36:64:55:66",
+        deviceClass : deviceClass,
+        isBonded : false,
+        isTrusted : true,
+        isConnected : true,
+        uuids : ["7bce4566-6c78-90ab-afer-6af108a36789"]
+    };
+    remoteDevs3 = {
+        name : "remoteDevs3",
+        address : "12:12:43:47:55:16",
+        deviceClass : deviceClass,
+        isBonded : false,
+        isTrusted : true,
+        isConnected : true,
+        uuids : ["84ce4566-6c78-9d3b-afer-6af108a36789"]
+    };
+    remoteDevs4 = {
+        name : "remoteDevs4",
+        address : "15:82:43:46:35:62",
+        deviceClass : deviceClass,
+        isBonded : false,
+        isTrusted : true,
+        isConnected : true,
+        uuids : ["6c7532ab-afe0-2ec1-08a3-08606c7890ab"]
+    };
+    remoteDevs5 = {
+        name : "remoteDevs5",
+        address : "32:23:65:25:55:66",
+        deviceClass : deviceClass,
+        isBonded : false,
+        isTrusted : true,
+        isConnected : true,
+        uuids : ["94316c75-32ab-afe0-2ec1-08a30860ce45"]
+    };
+    remoteDevs6 = {
+        name : "remoteDevs6",
+        address : "54:29:42:21:55:66",
+        deviceClass : deviceClass,
+        isBonded : false,
+        isTrusted : true,
+        isConnected : true,
+        uuids : ["32abafe0-4566-6c78-90ab-2ec108a30860"]
+    };
+    _remoteDevs.push(_remoteDevice);
+    _remoteDevs.push(remoteDevs1);
+    _remoteDevs.push(remoteDevs2);
+    _remoteDevs.push(remoteDevs3);
+    _remoteDevs.push(remoteDevs4);
+    _remoteDevs.push(remoteDevs5);
+    _remoteDevs.push(remoteDevs6);
+}
+
+event.on("deviceInit", function (remote) {
+    remote.pairedDevice = _remoteDevice;
+    remote.devices = _remoteDevs;
+});
+
+module.exports = {
+    panel : {
+        domId : "bluetooth-container",
+        collapsed : true,
+        pane: "left",
+        titleName: "Bluetooth",
+        display: true
+    },
+
+    initialize : function () {
+        _getRemoteDevs();
+
+        document.getElementById("accept-bonding").addEventListener("click", function () {
+            event.trigger("remoteDevBonded", ["bonding"]);
+            document.getElementById("operation-bonding").style.display = "none";
+        });
+
+        document.getElementById("cancel-bonding").addEventListener("click", function () {
+            if (_isBonding) {
+                event.trigger("remoteDevDetached", [_remoteDevice.address]);
+            } else {
+                event.trigger("remoteDevBonded", ["noBonding"]);
+            }
+            document.getElementById("operation-bonding").style.display = "none";
+            _isBonding = false;
+        });
+
+        document.getElementById("bluetooth-send").addEventListener("click", function () {
+            var remoteText = document.getElementById("bluetooth-text").value;
+            event.trigger("remoteDataArrived", [remoteText]);
+        });
+
+        document.getElementById("bluetooth-clear").addEventListener("click", function () {
+            document.getElementById("received-data").value = "";
+        });
+
+        document.getElementById("bluetooth-away").addEventListener("click", function () {
+            var isAway = document.getElementById("bluetooth-away").checked;
+            event.trigger("remoteDevAway", [isAway]);
+        });
+
+        event.on("bondingCreated", function (localDeviceName) {
+            var bondingText = "Give access permission for \"" + localDeviceName + "\"?";
+            document.getElementById("bluetooth-operation-label").innerHTML = bondingText;
+            document.getElementById("operation-bonding").style.display = "block";
+        });
+
+        event.on("bondingSucceeded", function (remote) {
+            _isBonding = true;
+            document.getElementById("bondPrompt").style.display = "block";
+        });
+
+        event.on("bondingDestroyed", function (remote) {
+            document.getElementById("bondPrompt").style.display = "none";
+            document.getElementById("operation-bonding").style.display = "none";
+        });
+
+        event.on("dataArrived", function (receivedData) {
+            if (document.getElementById("checkboxRFCOMM").checked)
+                document.getElementById("received-data").value = receivedData;
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/time', function (require, module, exports) {
+/*
+ *  Copyright 2012 Intel Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function _init() {
+    var db = require('ripple/db'),
+        utils = require('ripple/utils'),
+        allTZ, dbTZ, node = jQuery("#time-locale-select"),
+        timezone = require('ripple/platform/tizen/1.0/timezone_info'),
+        event = require('ripple/event'),
+        triggerNode = jQuery("#trigger-alarm-id"),
+        alarms, time, timeId;
+
+    function triggerAlarm() {
+        time = new Date();
+        alarms = db.retrieveObject("tizen1.0-db-alarms");
+        if (alarms !== null) {
+            utils.forEach(alarms, function (obj) {
+                if (obj.id !== undefined) {
+                    event.trigger("CheckAlarm", [obj.id]);
+                }
+            });
+        }
+    }
+    window.setInterval(triggerAlarm, 1000);
+
+    allTZ = timezone.getAllTimezone();
+    utils.forEach(allTZ, function (tz) {
+        node.append(utils.createElement("option", {
+            "value": tz,
+            "innerHTML": tz + " - " + timezone.getTimezoneAbbr(tz) + "(" + timezone.getTimezoneDiff(tz) + ")"
+        }));
+    });
+    dbTZ = db.retrieve("tizen-timezone");
+    if (timezone.isValidTimezone(dbTZ)) {
+        node.val(dbTZ);
+    } else {
+        db.save("tizen-timezone", node.val());
+    }
+    node.bind("change", function () {
+        db.save("tizen-timezone", node.val());
+    });
+/* FIXME: Node "trigger-alarm-id" will be removed from Time panel
+ *        due to "time" panel will changed to "time zone" panel(PTSDK-875)
+
+    event.on("SendTriggerAppId", function (applicationId) {
+        if (timeId !== undefined)
+            clearTimeout(timeId);
+        triggerNode.empty();
+        triggerNode.append(utils.createElement("p", {
+            "innerHTML": applicationId + " is triggered"
+        }));
+        triggerNode.show();
+        timeId = setTimeout("jQuery('#trigger-alarm-id').empty();", 10000);// Comments will disappear after 10s
+    });
+*/
+}
+
+module.exports = {
+    panel: {
+        domId: "time-container",
+        collapsed: true,
+        pane: "right",
+        titleName: "Time",
+        display: true
+    },
+    initialize: _init
+};
+
+});
+require.define('ripple/ui/plugins/settings', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var db = require('ripple/db'),
+    constants = require('ripple/constants'),
+    KEY = constants.XHR.PROXY_DISABLED_BUTTON; // TODO: one settings object for all
+
+function _saveAndReload(key, value) {
+    jWorkflow.order(function (prev, baton) {
+        baton.take();
+        db.save(key, value, null, baton.pass);
+    }).start(function () {
+        location.reload();
+    });
+}
+
+function _initialize(prev, baton) {
+    var select = document.getElementById("settings-xhr-proxy");
+    select.value = String(db.retrieve(KEY));
+    select.addEventListener("change", function () {
+        _saveAndReload(KEY, this.value);
+    }, false);
+    // TODO: reload here?
+}
+
+module.exports = {
+    panel: {
+        domId: "settings-container",
+        collapsed: true,
+        pane: "right"
+    },
+    initialize: _initialize
+};
+
+});
+require.define('ripple/ui/plugins/omnibar', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var emulatorBridge = require('ripple/emulatorBridge'),
+    db = require('ripple/db'),
+    event = require('ripple/event');
+
+function _omnibar() {
+    return document.querySelector(".omni-bar input");
+}
+
+function _persist(url) {
+    db.save("current-url", url);
+}
+
+function _persistRoot(url) {
+    db.save("root-url", url);
+}
+
+function _currentURL() {
+    return db.retrieve("current-url") || "about:blank";
+}
+
+function _rootURL() {
+    return db.retrieve("root-url") || "about:blank";
+}
+
+function _back() {
+    emulatorBridge.window().history.back();
+}
+
+function _forward() {
+    emulatorBridge.window().history.forward();
+}
+
+function _reload() {
+    emulatorBridge.window().location.reload();
+}
+
+event.on("FrameHistoryChange", function (url) {
+    _omnibar().value = url;
+    _persist(url);
+    _persistRoot(url);
+});
+
+module.exports = {
+    initialize: function (prev, baton) {
+        var omnibar = _omnibar(),
+            position, loc, tmp,
+            url, filename, matching,
+            xhr;
+
+        jQuery(".logo, .beta, .left, .right, .left-panel-collapse, .right-panel-collapse").css({
+            "marginTop": "35px"
+        });
+
+        jQuery("#settings-xhr-proxy").parent().parent().hide();
+
+        $(".omni-bar").show();
+
+        position = document.documentURI.indexOf("?url=");
+        if (position !== -1) {
+            url = document.documentURI.substring(position + 5, document.documentURI.length);
+            if (url.match(/^\.[\.]?/) !== null) {
+                loc = document.location;
+                filename = loc.pathname.replace(/^.*[\\\/]/, '')
+                matching = new RegExp(filename,"g");
+                tmp = loc.protocol + "//" + loc.hostname + loc.pathname.replace(matching, "") + url;
+                url = tmp;
+            }
+            _persist(url);
+            _persistRoot(url);
+            require('ripple/widgetConfig').initialize();
+            require('ripple/ui/plugins/widgetConfig').initialize();
+        }
+
+        omnibar.value = _currentURL();
+
+        omnibar.addEventListener("keydown", function (event) {
+            if (event.keyCode === '13' || event.keyCode === 13 || event.keyCode === '0' || event.keyCode === 0) { // enter or return
+                if (omnibar.value.trim() !== "") {
+                    if (_currentURL().match(/^file:/) && omnibar.value.match(/^file:/)) { // Use ajax to know whether that file exists
+                        xhr = new XMLHttpRequest();
+                        xhr.onreadystatechange = function () {
+                            if (xhr.readyState == 4) {
+                                if (xhr.responseText !== '') {
+                                    _persist(omnibar.value);
+                                    _persistRoot(omnibar.value);
+                                    emulatorBridge.window().location.assign(omnibar.value);
+                                } else {
+                                    alert("File doesn't exist!");
+                                    return;
+                                }
+                            }
+                        };
+                        xhr.open('GET', omnibar.value, true);
+                        xhr.send(null);
+                    } else {
+                        //default the protocal if not provided
+                        omnibar.value = omnibar.value.indexOf("://") < 0 ? "http://" + omnibar.value : omnibar.value;
+                        _persist(omnibar.value);
+                        _persistRoot(omnibar.value);
+                        emulatorBridge.window().location.assign(omnibar.value);
+                    }
+                }
+            }
+        });
+
+        window.addEventListener("keydown", function (event) {
+            var hasMetaOrAltPressed = (event.metaKey || event.ctrlKey),
+                key = parseInt(event.keyCode, 10);
+
+            if (key === 37 && hasMetaOrAltPressed) { // cmd/ctrl + left arrow
+                event.preventDefault();
+                _back();
+            }
+
+            if (key === 39 && hasMetaOrAltPressed) { // cmd/ctrl + right arrow
+                event.preventDefault();
+                _forward();
+            }
+
+            if (key === 82 && hasMetaOrAltPressed) { // cmd/ctrl + r
+                event.preventDefault();
+                _reload();
+            }
+
+            if (key === 116) { // F5
+                event.preventDefault();
+                _reload();
+            }
+        });
+
+        document.getElementById("history-back").addEventListener("click", _back);
+        document.getElementById("history-forward").addEventListener("click", _forward);
+        document.getElementById("history-reload").addEventListener("click", _reload);
+    },
+    currentURL: function () {
+        return _currentURL();
+    },
+    rootURL: function () {
+        return _rootURL();
+    }
+};
+
+});
+require.define('ripple/ui/plugins/messaging', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    _type = {
+        sms: "SMS",
+        mms: "MMS",
+        email: "E-mail"
+    },
+    _filename_suffix = 0,
+    _attachments = [];
+
+function _getAttachmentFileName() {
+    return "attach" + _filename_suffix + ".txt";
+}
+
+module.exports = {
+    panel: {
+        domId: "messaging-container",
+        collapsed: true,
+        pane: "left",
+        titleName: "Messaging",
+        display: true
+    },
+    initialize: function () {
+        document.getElementById("messaging-send")
+            .addEventListener("click", function () {
+                var number = document.getElementById("messaging-sms-number").value,
+                    text = document.getElementById("messaging-text").value,
+                    type = document.getElementById("messaging-type").value,
+                    message = {
+                        type: type,
+                        body: text,
+                        from: number,
+                        time: new Date(),
+                        attachments: _attachments
+                    };
+
+                event.trigger("MessageReceived", [message]);
+                
+                _attachments = [];
+/* TODO: add back when attachment is finished
+                document.getElementById("messaging-attachments").innerHTML = "";
+*/
+                _filename_suffix = 0;
+            }, false);
+
+/* TODO: add back when attachment is finished
+        document.getElementById("messaging-attach")
+            .addEventListener("click", function () {
+                var attachedFile, attachedFileCheckbox, attachedFileName;
+                if (_filename_suffix > 0)
+                    return;
+                _attachments.push({filename: _getAttachmentFileName(), content: document.getElementById("messaging-attachment-content").value});
+
+                attachedFile = document.getElementById("messaging-attachments").insertRow(0);
+                attachedFileName = attachedFile.insertCell(0);
+                attachedFileCheckbox = attachedFile.insertCell(1);
+                attachedFileName.innerHTML = _attachments[_filename_suffix].filename;
+//                attachedFileCheckbox.innerHTML = '<input type="checkbox" value="' + _filename_suffix + '">';
+
+                document.getElementById("messaging-attachment-content").value = "";
+                _filename_suffix++;
+            }, false);
+
+        document.getElementById("messaging-detach")
+            .addEventListener("click", function () {
+                _attachments = [];
+                document.getElementById("messaging-attachments").innerHTML = "";
+                _filename_suffix = 0;
+            }, false);
+*/
+        event.on("OutsideMessageReceived", function (message) {
+            var numRecipients = 0,
+                i = 0,
+                recipients = [],
+                recipientsStatus = {},
+                strRecipients = document.getElementById("messaging-recipients").value;
+
+            recipientsStatus.id = message.id;
+            recipientsStatus.msg = message.msg;
+            for (i in message.to) {
+                recipientsStatus[message.to[i]] = true;
+                recipients.push(message.to[i]);
+            }
+            for (i in message.cc) {
+                recipientsStatus[message.cc[i]] = true;
+                recipients.push(message.cc[i]);
+            }
+            for (i in message.bcc) {
+                recipientsStatus[message.bcc[i]] = true;
+                recipients.push(message.bcc[i]);
+            }
+            numRecipients = recipients.length;
+            strRecipients = recipients.join(",");
+            event.trigger("MessageSent", [recipientsStatus]);
+            document.getElementById("messaging-received").innerHTML = "" + numRecipients + " recipient(s)" + " delivered";
+            document.getElementById("messaging-recipients").value = strRecipients;
+            document.getElementById("received-message-box").value = message.body;
+        });
+        
+        document.getElementById("messaging-clear")
+            .addEventListener("click", function () {
+                document.getElementById("received-message-box").value = "";
+                document.getElementById("messaging-received").innerHTML = "";
+            }, false);
+        
+        utils.forEach(_type, function (msgTypeText, msgType) {
+            var typeNode = utils.createElement("option", {
+                    "innerText": msgTypeText,
+                    "value": msgType
+                });
+
+            document.getElementById("messaging-type").appendChild(typeNode);
+        });
+    }
+};
+
+});
+require.define('ripple/ui/plugins/about-dialog', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils');
+
+module.exports = {
+    initialize: function () {
+        $("#about-dialog").dialog({
+            resizable: false,
+            draggable: false,
+            modal: true,
+            autoOpen: false,
+            position: 'center',
+            minWidth: '464',
+            minHeight: '262'
+        });
+    },
+    show: function () {
+        //TODO: Restore this line once framework issue is resolved
+        //var port =  window.stagewebview ? stagewebview.serverPort : "9900";
+        var port = "9900";
+
+        $.ajax({
+            url: "http://127.0.0.1:" + port + "/ripple/about",
+            async: true,
+            success: function (resp) {
+                $("#about-dialog-ripple-build-deploy-version").html("(v" + resp.data.version + ")");
+            }
+        });
+
+        $.ajax({
+            url: utils.rippleLocation() + "package.json",
+            async: true,
+            success: function (resp) {
+                $("#about-dialog-ripple-ui-version").html("(v" + resp.version + ")");
+            }
+        });
+
+        $("#about-dialog").dialog("open");
+    }
+};
+
+});
+require.define('ripple/ui/plugins/themeSwitcher', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    db = require('ripple/db'),
+    THEME_KEY = "ui-theme",
+    THEME_SELECTOR = "#theme-select",
+    _currentTheme;
+
+function _saveAndReload(key, value) {
+    jWorkflow.order(function (prev, baton) {
+                baton.take();
+                db.save(key, value, null, baton.pass);
+            }).start(function () {
+                        location.reload();
+                    });
+}
+
+module.exports = {
+    initialize: function () {
+        var themeToSet = db.retrieve(THEME_KEY);
+
+       // Hide the theme switcher and always set the theme to light
+        jQuery(".theme-switcher").hide();
+               if (themeToSet !== "light") {
+            _saveAndReload(THEME_KEY, "light");
+               }
+               return;
+    }
+};
+
+});
+require.define('ripple/ui/plugins/platform', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var constants = require('ripple/constants'),
+    event = require('ripple/event'),
+    utils = require('ripple/utils'),
+    devices = require('ripple/devices'),
+    platform = require('ripple/platform'),
+    resizer = require('ripple/resizer'),
+    tooltip = require('ripple/ui/plugins/tooltip'),
+    db = require('ripple/db');
+
+function _animateChangePlatformButton() {
+    jQuery("#change-platform")
+        .animate({opacity: 0.5}, 500)
+        .animate({opacity: 1}, 500)
+        .animate({opacity: 0.5}, 500)
+        .animate({opacity: 1}, 500)
+        .animate({opacity: 0.5}, 500)
+        .animate({opacity: 1}, 500);
+}
+
+function _updatePlatformDeviceSelect(platformID, currentDeviceKey) {
+    var deviceInfoArray = devices.getDevicesForPlatform(platformID),
+        devicesSelect = document.getElementById(constants.COMMON.DEVICE_SELECT_ID),
+        i, sortedDeviceInfoArray, deviceNode;
+
+    devicesSelect.innerHTML = "";
+
+    sortedDeviceInfoArray = deviceInfoArray.sort(function (a, b) {
+        return a.screen.width > b.screen.width;
+    });
+
+    for (i = 0; i < sortedDeviceInfoArray.length; i += 1) {
+        deviceNode = utils.createElement("option", {
+            "innerText": sortedDeviceInfoArray[i].name,
+            "value": sortedDeviceInfoArray[i].id
+        });
+
+        if (currentDeviceKey && deviceNode.value === currentDeviceKey) {
+            deviceNode.selected = true;
+        }
+
+        devicesSelect.appendChild(deviceNode);
+    }
+}
+
+function changePlatformOrDevice() {
+    var platformId = jQuery("#platform-select").val(),
+        version = jQuery("#version-select").val(),
+        device = jQuery("#device-select").val();
+
+    platform.changeEnvironment({
+        "name": platformId,
+        "version": version
+    }, device, function () {
+        location.reload();
+    });
+}
+
+module.exports = {
+    panel: {
+        domId: "platforms-container",
+        collapsed: true,
+        pane: "left",
+        titleName: "Platform API",
+        display: true
+    },
+    initialize: function () {
+        var currentPlatform = platform.current().id,
+            currentVersion = platform.current().version,
+            platformList = platform.getList(),
+            platformSelect = document.getElementById(constants.COMMON.PLATFORM_SELECT_ID),
+            versionSelect = document.getElementById("version-select"),
+            currentDeviceKey = devices.getCurrentDevice().id,
+            platformNode, versionNode;
+
+        jQuery("#platform-select").bind("change", function () {
+            var newPlatform = jQuery(this).val(),
+                newDevice = jQuery("#device-select").val();
+
+            jQuery(versionSelect).children("option").remove();
+
+            utils.forEach(platformList, function (platform) {
+                utils.forEach(platform, function (version, versionNumber) {
+                    if (newPlatform === version.id) {
+                        versionSelect.appendChild(utils.createElement("option", {
+                            "innerText": versionNumber,
+                            "value":  versionNumber
+                        }));
+                    }
+                });
+            });
+
+            _updatePlatformDeviceSelect(newPlatform, newDevice);
+
+            jQuery("#" + constants.COMMON.DEVICE_SELECT_ID).effect("highlight", {color: "#62B4C8"}, 500, function () {
+                _animateChangePlatformButton();
+            });
+        });
+
+
+        jQuery("#change-platform").bind("click", changePlatformOrDevice);
+        jQuery("#device-select").bind("change", changePlatformOrDevice);
+
+        utils.forEach(platformList, function (platform, platformKey) {
+            platformNode = utils.createElement("option", {
+                "innerText": platformKey,
+                "value":  platformKey
+            });
+
+            utils.forEach(platform, function (version, versionNumber) {
+                versionNode = utils.createElement("option", {
+                    "innerText": versionNumber,
+                    "value":  versionNumber
+                });
+
+                if (currentPlatform && version.id === currentPlatform) {
+                    if (currentVersion && currentVersion === versionNumber) {
+                        platformNode.selected = true;
+                        versionNode.selected = true;
+                    }
+                }
+
+                versionSelect.appendChild(versionNode);
+            });
+            platformSelect.appendChild(platformNode);
+        });
+
+        _updatePlatformDeviceSelect(currentPlatform, currentDeviceKey);
+
+        tooltip.create("#" +  constants.COMMON.CHANGE_PLATFORM_BUTTON_ID, "Clicking the button will reload your page.");
+    }
+};
+
+});
+require.define('ripple/ui/plugins/tooltip', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var utils = require('ripple/utils'),
+    _options = {
+        track: true,
+        delay: 0,
+        showURL: false,
+        fade: 250,
+        extraClass: "ui-state-highlight ui-corner-all"
+    };
+
+module.exports = {
+    create: function (element, message) {
+        var options = utils.copy(_options);
+
+        options.bodyHandler = function () {
+            return message;
+        };
+
+        return jQuery(element).tooltip(options);
+    },
+
+    toggle: function () {
+        jQuery.tooltip.block();
+        return this.isOff();
+    },
+
+    isOff: function () {
+        return jQuery.tooltip.blocked;
+    }
+};
+
+});
+require.define('ripple/ui/themes', function (require, module, exports) {
+/*
+ *  Copyright 2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+module.exports = ["dark", "light"];
+
+});
+require('ripple/ui').register('omnibar');require('ripple/bootstrap').bootstrap();
\ No newline at end of file
diff --git a/web/themes/dark/images/device.png b/web/themes/dark/images/device.png
new file mode 100644 (file)
index 0000000..ae669b4
Binary files /dev/null and b/web/themes/dark/images/device.png differ
diff --git a/web/themes/dark/images/ui-bg_flat_25_222222_40x100.png b/web/themes/dark/images/ui-bg_flat_25_222222_40x100.png
new file mode 100644 (file)
index 0000000..dfd103c
Binary files /dev/null and b/web/themes/dark/images/ui-bg_flat_25_222222_40x100.png differ
diff --git a/web/themes/dark/images/ui-bg_flat_30_cccccc_40x100.png b/web/themes/dark/images/ui-bg_flat_30_cccccc_40x100.png
new file mode 100644 (file)
index 0000000..5473aff
Binary files /dev/null and b/web/themes/dark/images/ui-bg_flat_30_cccccc_40x100.png differ
diff --git a/web/themes/dark/images/ui-bg_flat_50_1e1e1e_40x100.png b/web/themes/dark/images/ui-bg_flat_50_1e1e1e_40x100.png
new file mode 100644 (file)
index 0000000..84ffa32
Binary files /dev/null and b/web/themes/dark/images/ui-bg_flat_50_1e1e1e_40x100.png differ
diff --git a/web/themes/dark/images/ui-bg_glass_40_ffc73d_1x400.png b/web/themes/dark/images/ui-bg_glass_40_ffc73d_1x400.png
new file mode 100644 (file)
index 0000000..d683a41
Binary files /dev/null and b/web/themes/dark/images/ui-bg_glass_40_ffc73d_1x400.png differ
diff --git a/web/themes/dark/images/ui-bg_highlight-hard_30_5871a3_1x100.png b/web/themes/dark/images/ui-bg_highlight-hard_30_5871a3_1x100.png
new file mode 100644 (file)
index 0000000..6731ae2
Binary files /dev/null and b/web/themes/dark/images/ui-bg_highlight-hard_30_5871a3_1x100.png differ
diff --git a/web/themes/dark/images/ui-bg_highlight-soft_0_333333_1x100.png b/web/themes/dark/images/ui-bg_highlight-soft_0_333333_1x100.png
new file mode 100644 (file)
index 0000000..1ba8838
Binary files /dev/null and b/web/themes/dark/images/ui-bg_highlight-soft_0_333333_1x100.png differ
diff --git a/web/themes/dark/images/ui-bg_highlight-soft_10_333333_1x100.png b/web/themes/dark/images/ui-bg_highlight-soft_10_333333_1x100.png
new file mode 100644 (file)
index 0000000..2bf8536
Binary files /dev/null and b/web/themes/dark/images/ui-bg_highlight-soft_10_333333_1x100.png differ
diff --git a/web/themes/dark/images/ui-bg_highlight-soft_20_333333_1x100.png b/web/themes/dark/images/ui-bg_highlight-soft_20_333333_1x100.png
new file mode 100644 (file)
index 0000000..4384aa6
Binary files /dev/null and b/web/themes/dark/images/ui-bg_highlight-soft_20_333333_1x100.png differ
diff --git a/web/themes/dark/images/ui-bg_highlight-soft_50_1e1e1e_1x100.png b/web/themes/dark/images/ui-bg_highlight-soft_50_1e1e1e_1x100.png
new file mode 100644 (file)
index 0000000..88c46e9
Binary files /dev/null and b/web/themes/dark/images/ui-bg_highlight-soft_50_1e1e1e_1x100.png differ
diff --git a/web/themes/dark/images/ui-icons_222222_256x240.png b/web/themes/dark/images/ui-icons_222222_256x240.png
new file mode 100644 (file)
index 0000000..b273ff1
Binary files /dev/null and b/web/themes/dark/images/ui-icons_222222_256x240.png differ
diff --git a/web/themes/dark/images/ui-icons_5871a3_256x240.png b/web/themes/dark/images/ui-icons_5871a3_256x240.png
new file mode 100644 (file)
index 0000000..de1b69d
Binary files /dev/null and b/web/themes/dark/images/ui-icons_5871a3_256x240.png differ
diff --git a/web/themes/dark/images/ui-icons_a83300_256x240.png b/web/themes/dark/images/ui-icons_a83300_256x240.png
new file mode 100644 (file)
index 0000000..95993ea
Binary files /dev/null and b/web/themes/dark/images/ui-icons_a83300_256x240.png differ
diff --git a/web/themes/dark/images/ui-icons_cccccc_256x240.png b/web/themes/dark/images/ui-icons_cccccc_256x240.png
new file mode 100644 (file)
index 0000000..9254e05
Binary files /dev/null and b/web/themes/dark/images/ui-icons_cccccc_256x240.png differ
diff --git a/web/themes/dark/images/ui-icons_ffffff_256x240.png b/web/themes/dark/images/ui-icons_ffffff_256x240.png
new file mode 100644 (file)
index 0000000..42f8f99
Binary files /dev/null and b/web/themes/dark/images/ui-icons_ffffff_256x240.png differ
diff --git a/web/themes/dark/theme.css b/web/themes/dark/theme.css
new file mode 100644 (file)
index 0000000..95c89b5
--- /dev/null
@@ -0,0 +1,534 @@
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+*/
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0;}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helevetica,%20Arial,%20sans-serif&fwDefault=normal&fsDefault=12px&cornerRadius=6px&bgColorHeader=333333&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=10&borderColorHeader=333333&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=222222&bgTextureContent=01_flat.png&bgImgOpacityContent=25&borderColorContent=222222&fcContent=ffffff&iconColorContent=cccccc&bgColorDefault=333333&bgTextureDefault=03_highlight_soft.png&bgImgOpacityDefault=20&borderColorDefault=333333&fcDefault=eeeeee&iconColorDefault=cccccc&bgColorHover=1e1e1e&bgTextureHover=03_highlight_soft.png&bgImgOpacityHover=50&borderColorHover=1e1e1e&fcHover=ffffff&iconColorHover=ffffff&bgColorActive=3c8b9e&bgTextureActive=04_highlight_hard.png&bgImgOpacityActive=30&borderColorActive=3c8b9e&fcActive=ffffff&iconColorActive=222222&bgColorHighlight=1e1e1e&bgTextureHighlight=04_highlight_hard.png&bgImgOpacityHighlight=0&borderColorHighlight=1e1e1e&fcHighlight=f0f0f0&iconColorHighlight=5871a3&bgColorError=be1c19&bgTextureError=02_glass.png&bgImgOpacityError=0&borderColorError=be1c19&fcError=ffffff&iconColorError=ffffff&bgColorOverlay=1e1e1e&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=50&opacityOverlay=80&bgColorShadow=cccccc&bgTextureShadow=01_flat.png&bgImgOpacityShadow=30&opacityShadow=60&thicknessShadow=7px&offsetTopShadow=-7px&offsetLeftShadow=-7px&cornerRadiusShadow=8px
+*/
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget, .main { font-family: Helevetica, Arial, sans-serif; font-size: 1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Helevetica, Arial, sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #222222; background: #222222 url(images/ui-bg_flat_25_222222_40x100.png) 50% 50% repeat-x; color: #ffffff; }
+body { background: #222222 url(images/ui-bg_flat_25_222222_40x100.png) 50% 50% repeat-x;}
+.ui-widget-content, .main a { color: #ffffff; }
+.ui-widget-header { border: 1px solid #333333; background: #333333 url(images/ui-bg_highlight-soft_10_333333_1x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
+.ui-widget-header a { color: #ffffff; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #333333; background: #333333 url(images/ui-bg_highlight-soft_20_333333_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #eeeeee; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #eeeeee; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #1e1e1e; background: #1e1e1e url(images/ui-bg_highlight-soft_50_1e1e1e_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #ffffff; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #3c8b9e; background: #3c8b9e; font-weight: normal; color: #ffffff; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #1e1e1e; background: #333333; color: #f0f0f0; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #f0f0f0; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #be1c19; background: #be1c19; color: #ffffff; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_cccccc_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_cccccc_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_cccccc_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_5871a3_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
+
+#layout-portrait, #layout-landscape {
+    background: url(images/device.png) center no-repeat;
+}
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; }
+.ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
+.ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
+.ui-corner-top { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
+.ui-corner-right {  -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
+.ui-corner-left { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
+.ui-corner-all { -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #cccccc url(images/ui-bg_flat_30_cccccc_40x100.png) 50% 50% repeat-x; opacity: 0.35;filter:Alpha(Opacity=35); }
+.ui-widget-shadow { margin: -7px 0 0 -7px; padding: 7px; background: #cccccc url(images/ui-bg_flat_30_cccccc_40x100.png) 50% 50% repeat-x; opacity: .60;filter:Alpha(Opacity=60); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* Resizable
+----------------------------------*/
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Selectable
+----------------------------------*/
+.ui-selectable-helper { border:1px dotted black }
+/* Accordion
+----------------------------------*/
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; }
+.ui-accordion .ui-accordion-li-fix { display: inline; }
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
+.ui-accordion .ui-accordion-content-active { display: block; }/* Autocomplete
+----------------------------------*/
+.ui-autocomplete { position: absolute; cursor: default; }
+.ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; }
+
+/* Menu
+----------------------------------*/
+.ui-menu {
+    list-style:none;
+    padding: 2px;
+    margin: 0;
+    display:block;
+}
+.ui-menu .ui-menu {
+    margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+    margin:0;
+    padding: 0;
+    float: left;
+    clear: left;
+    width: 100%;
+}
+.ui-menu .ui-menu-item a {
+    text-decoration:none;
+    display:block;
+    padding:.2em .4em;
+    line-height:1.5;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+    font-weight: normal;
+    margin: -1px;
+}
+/* Button
+----------------------------------*/
+
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; }
+button.ui-button-icons-only { width: 3.7em; }
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4;  }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+
+
+
+/* Dialog
+----------------------------------*/
+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative;  }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/* Slider
+----------------------------------*/
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
+----------------------------------*/
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
+/* Datepicker
+----------------------------------*/
+.ui-datepicker { width: 17em; padding: .2em .2em 0; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* Progressbar
+----------------------------------*/
+.ui-progressbar { height:2em; text-align: left; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
+
+
+/*Custom styles
+----------------------------------*/
+
+/*text
+---------------*/
+.ui-text-label { font-weight: bold;  color: #62b4c8;}
+.ui-text-beta { color: #FFFFFF; }
+.ui-text-highlight { color: #daa520;}
+.ui-text-pass { color: #80ac27 !important;}
+.ui-text-fail { color: #ff4500 !important;}
+.ui-text-missing { color: #ffffff !important;}
+
+
+/*accordion*/
+.ui-accordion .ui-accordion-header { padding-left: 20px; margin-top: 5px;} 
+.ui-accordion .ui-state-default { background: #1e1e1e; border: 1px solid #1e1e1e; }
+.ui-accordion .ui-state-hover { background: #333333; border: 1px solid #1e1e1e; }
+.ui-accordion .ui-state-active { background: #333333; border: 1px solid #333333; }
+.ui-accordion .ui-accordion-content-active { border: 1px solid #333333; }
+
+/*state effects*/
+.main button:hover, .main select:hover {
+    border: 1px solid #1e1e1e;
+    background: #1e1e1e url(images/ui-bg_highlight-soft_50_1e1e1e_1x100.png) 50% 50% repeat-x;
+    font-weight: normal;
+    color: #ffffff;
+}
+
+.main button:active,
+.main textarea:hover,
+.main textarea:active,
+.main input[type^=text]:focus, .main input[type^=number]:focus,
+.main input[type^=text]:hover, .main input[type^=number]:hover {
+    border: 1px solid #3c8b9e;
+    background: #3c8b9e;
+    font-weight: normal;
+    color: #ffffff;
+}
+
+.ui-sortable-highlight {
+    background: #1e1e1e;
+}
+
+.first-run-window {    
+    background-color: rgba(30, 30, 30, 1);    
+}
+
+.platform-select-dialog {    
+    color: #F0F0F0;    
+}
+
+.panel-table td {
+    color: white;
+}
+
+input[type="number"]::-webkit-outer-spin-button,
+input[type="number"]::-webkit-inner-spin-button {
+    -webkit-appearance: none;
+    margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
+}
diff --git a/web/themes/light/images/device.png b/web/themes/light/images/device.png
new file mode 100644 (file)
index 0000000..ebee763
Binary files /dev/null and b/web/themes/light/images/device.png differ
diff --git a/web/themes/light/images/ui-anim_basic_16x16.gif b/web/themes/light/images/ui-anim_basic_16x16.gif
new file mode 100644 (file)
index 0000000..085ccae
Binary files /dev/null and b/web/themes/light/images/ui-anim_basic_16x16.gif differ
diff --git a/web/themes/light/images/ui-bg_flat_0_aaaaaa_40x100.png b/web/themes/light/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644 (file)
index 0000000..5b5dab2
Binary files /dev/null and b/web/themes/light/images/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/web/themes/light/images/ui-bg_flat_75_ffffff_40x100.png b/web/themes/light/images/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644 (file)
index 0000000..ac8b229
Binary files /dev/null and b/web/themes/light/images/ui-bg_flat_75_ffffff_40x100.png differ
diff --git a/web/themes/light/images/ui-bg_glass_55_fbf9ee_1x400.png b/web/themes/light/images/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100644 (file)
index 0000000..ad3d634
Binary files /dev/null and b/web/themes/light/images/ui-bg_glass_55_fbf9ee_1x400.png differ
diff --git a/web/themes/light/images/ui-bg_glass_65_ffffff_1x400.png b/web/themes/light/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644 (file)
index 0000000..42ccba2
Binary files /dev/null and b/web/themes/light/images/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/web/themes/light/images/ui-bg_glass_75_dadada_1x400.png b/web/themes/light/images/ui-bg_glass_75_dadada_1x400.png
new file mode 100644 (file)
index 0000000..5a46b47
Binary files /dev/null and b/web/themes/light/images/ui-bg_glass_75_dadada_1x400.png differ
diff --git a/web/themes/light/images/ui-bg_glass_75_e6e6e6_1x400.png b/web/themes/light/images/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100644 (file)
index 0000000..86c2baa
Binary files /dev/null and b/web/themes/light/images/ui-bg_glass_75_e6e6e6_1x400.png differ
diff --git a/web/themes/light/images/ui-bg_glass_95_fef1ec_1x400.png b/web/themes/light/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644 (file)
index 0000000..4443fdc
Binary files /dev/null and b/web/themes/light/images/ui-bg_glass_95_fef1ec_1x400.png differ
diff --git a/web/themes/light/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/web/themes/light/images/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100644 (file)
index 0000000..7c9fa6c
Binary files /dev/null and b/web/themes/light/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ
diff --git a/web/themes/light/images/ui-icons_222222_256x240.png b/web/themes/light/images/ui-icons_222222_256x240.png
new file mode 100644 (file)
index 0000000..b273ff1
Binary files /dev/null and b/web/themes/light/images/ui-icons_222222_256x240.png differ
diff --git a/web/themes/light/images/ui-icons_2e83ff_256x240.png b/web/themes/light/images/ui-icons_2e83ff_256x240.png
new file mode 100644 (file)
index 0000000..09d1cdc
Binary files /dev/null and b/web/themes/light/images/ui-icons_2e83ff_256x240.png differ
diff --git a/web/themes/light/images/ui-icons_454545_256x240.png b/web/themes/light/images/ui-icons_454545_256x240.png
new file mode 100644 (file)
index 0000000..59bd45b
Binary files /dev/null and b/web/themes/light/images/ui-icons_454545_256x240.png differ
diff --git a/web/themes/light/images/ui-icons_888888_256x240.png b/web/themes/light/images/ui-icons_888888_256x240.png
new file mode 100644 (file)
index 0000000..6d02426
Binary files /dev/null and b/web/themes/light/images/ui-icons_888888_256x240.png differ
diff --git a/web/themes/light/images/ui-icons_cd0a0a_256x240.png b/web/themes/light/images/ui-icons_cd0a0a_256x240.png
new file mode 100644 (file)
index 0000000..2ab019b
Binary files /dev/null and b/web/themes/light/images/ui-icons_cd0a0a_256x240.png differ
diff --git a/web/themes/light/theme.css b/web/themes/light/theme.css
new file mode 100644 (file)
index 0000000..5eb3276
--- /dev/null
@@ -0,0 +1,574 @@
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+*/
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica,Arial,sans-serif&fwDefault=normal&fsDefault=1em&cornerRadius=6px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
+*/
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget, .main { font-family: Helvetica,Arial,sans-serif; font-size: 1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Helvetica,Arial,sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #CCCCCC; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
+body { background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x;}
+.ui-widget-content a, .main a { color: #222222; }
+.ui-widget-header { border: 1px solid #CCCCCC; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
+.ui-widget-header a { color: #222222; }
+
+/* Interaction states
+----------------------------------*/
+.ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { 
+border: 1px solid #aaaaaa; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #444444; }
+.ui-state-default { 
+    border: 1px solid #9b9fa1; 
+    background: #e6e6e6;
+    background-image: -webkit-linear-gradient(top, #FFFFFF 41%, #E5E5E5 57%);
+    background-image: -webkit-gradient(
+        linear,
+        left top,
+        left bottom,
+        color-stop(0.41, #FFFFFF),
+        color-stop(0.57, #E5E5E5)); 
+}
+    
+
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #CCCCCC; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+
+.ui-box-TitleImage {
+    width:10px; 
+    height:10px; 
+    margin-right: 10px; 
+    margin-left: 2px;
+    display: inline-block; 
+}
+
+.ui-box-TitleImageClosed {
+    background-image: url('../../images/closedArrowIcon.png'); 
+    background-repeat: no-repeat; 
+}
+
+.ui-box-TitleImageOpen {
+    background-image: url('../../images/openArrowIcon.png'); 
+    background-repeat: no-repeat; 
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
+
+#layout-portrait, #layout-landscape {
+    background: url(images/device.png) center no-repeat;
+}
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; }
+.ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
+.ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
+.ui-corner-top { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
+.ui-corner-right {  -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
+.ui-corner-left { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
+.ui-corner-all { -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+
+/* Overlays */
+.ui-widget-overlay { background: rgba(21, 28, 34, 0.85) }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #CCCCCC url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* Resizable
+----------------------------------*/
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Selectable
+----------------------------------*/
+.ui-selectable-helper { border:1px dotted black }
+/* Accordion
+----------------------------------*/
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
+.ui-accordion .ui-accordion-li-fix { display: inline; }
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
+/* IE7-/Win - Fix extra vertical space in lists */
+.ui-accordion a { zoom: 1; }
+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
+.ui-accordion .ui-accordion-content-active { display: block; }/* Autocomplete
+----------------------------------*/
+.ui-autocomplete { position: absolute; cursor: default; }    
+.ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; }
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+
+/* Menu
+----------------------------------*/
+.ui-menu {
+    list-style:none;
+    padding: 2px;
+    margin: 0;
+    display:block;
+}
+.ui-menu .ui-menu {
+    margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+    margin:0;
+    padding: 0;
+    zoom: 1;
+    float: left;
+    clear: left;
+    width: 100%;
+}
+.ui-menu .ui-menu-item a {
+    text-decoration:none;
+    display:block;
+    padding:.2em .4em;
+    line-height:1.5;
+    zoom:1;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+    font-weight: normal;
+    margin: -1px;
+}
+/* Button
+----------------------------------*/
+
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; } 
+button.ui-button-icons-only { width: 3.7em; } 
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4;  }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+
+
+/* Dialog
+----------------------------------*/
+.ui-dialog { position: absolute; padding: 0.8em; width: 300px; overflow: hidden; background: rgba(25,32,40,0.80); border-width: 0px;}
+.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative;  }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; } 
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/* Slider
+----------------------------------*/
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
+----------------------------------*/
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
+/* Datepicker
+----------------------------------*/
+.ui-datepicker { width: 17em; padding: .2em .2em 0; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month, 
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+
+----------------------------------*/
+.ui-progressbar { height:2em; text-align: left; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
+
+
+/*text
+---------------*/
+.ui-text-label { font-size:12px; font-weight: bold;  color: #333;}
+.ui-text-beta { color: #1e1e1e; }
+.ui-text-highlight { color: #daa520;}
+.ui-text-pass { color: #80ac27 !important;}
+.ui-text-fail { color: #ff4500 !important;}
+.ui-text-missing { color: #555555 !important;}
+
+/*accordion*/
+.ui-accordion .ui-accordion-header { padding-left: 20px; margin-top: 5px;}
+.ui-accordion .ui-state-active {  border: 1px solid #AAAAAA; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121;}
+.ui-accordion .ui-accordion-content { margin-bottom: 5px;}
+
+/*state effects*/
+
+.main textarea:hover,
+.main textarea:active,
+.main input[type^=text]:focus, .main input[type^=number]:focus,
+.main input[type^=text]:hover, .main input[type^=number]:hover {
+    border: 1px solid #CCCCCC;
+    background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;
+    font-weight: normal;
+    color: #212121;
+}
+
+.ui-sortable-highlight {
+    background: #dadada;
+}
+
+.info {
+    border: 1px solid #FFFFFF;
+}
+
+.error-window {    
+    background-color: #2B0000;    
+}
+
+.error-dialog {    
+    color: #212121;
+}
+.first-run-window {    
+    background-color: rgba(218, 218, 218, 1);    
+}
+
+.platform-select-dialog {    
+    color: #212121;
+}
+
+.panel-table td {
+    color: #222;
+}
+
+input[type="number"]::-webkit-outer-spin-button,
+input[type="number"]::-webkit-inner-spin-button {
+    -webkit-appearance: none;
+    margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
+}
+
+