>();
     private static int mDeletedPlugins = 0;
 
+    private IITC_FileManager mFileManager;
+
     @Override
     public void setListAdapter(final ListAdapter adapter) {
         if (adapter == null) {
@@ -78,6 +85,13 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
             getIntent()
                     .putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, PluginsFragment.class.getName());
         }
+
+        mFileManager = new IITC_FileManager(this);
+
+        final String uri = getIntent().getStringExtra("url");
+        if (uri != null) {
+            mFileManager.installPlugin(uri, true);
+        }
         super.onCreate(savedInstanceState);
     }
 
@@ -103,17 +117,53 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
         }
     }
 
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.plugins, menu);
+        return super.onCreateOptionsMenu(menu);
+    }
+
     @Override
     public boolean onOptionsItemSelected(final MenuItem item) {
         switch (item.getItemId()) {
             case android.R.id.home: // exit settings when home button (iitc icon) is pressed
                 onBackPressed();
                 return true;
+            case R.id.menu_plugins_add:
+                // create the chooser Intent
+                final Intent target = new Intent(Intent.ACTION_GET_CONTENT);
+                // iitcm only parses *.user.js scripts
+                target.setType("file/*");
+                target.addCategory(Intent.CATEGORY_OPENABLE);
+
+                try {
+                    startActivityForResult(Intent.createChooser(target, "Choose file"), COPY_PLUGIN_REQUEST);
+                } catch (final ActivityNotFoundException e) {
+                    Toast.makeText(this, "No activity to select a file found." +
+                            "Please install a file browser of your choice!", Toast.LENGTH_LONG).show();
+                }
             default:
                 return super.onOptionsItemSelected(item);
         }
     }
 
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch(requestCode) {
+            case COPY_PLUGIN_REQUEST:
+                if (data != null && data.getData() != null) {
+                    String filePath = data.getData().getPath();
+                    mFileManager.installPlugin("file://" + filePath, true);
+                    return;
+                }
+                break;
+            default:
+                super.onActivityResult(requestCode, resultCode, data);
+                break;
+
+        }
+    }
+
     @Override
     protected boolean isValidFragment(final String s) {
         return true;
@@ -141,9 +191,7 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
     }
 
     private File[] getUserPlugins() {
-        final String iitc_path = Environment.getExternalStorageDirectory().getPath()
-                + "/IITC_Mobile/";
-        final File directory = new File(iitc_path + "plugins/");
+        final File directory = new File(IITC_FileManager.PLUGINS_PATH);
         File[] files = directory.listFiles();
         if (files == null) {
             files = new File[0];
@@ -164,6 +212,8 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
         if ((userPlugins.length + officialPlugins.length) != (numPlugins + mDeletedPlugins)) {
             Log.d("new or less plugins found since last start, rebuild preferences");
             sAssetPlugins.clear();
+            sUserPlugins.clear();
+            mDeletedPlugins = 0;
             setUpPluginPreferenceScreen();
         }
     }
diff --git a/plugins/bookmarks-by-zaso.user.js b/plugins/bookmarks-by-zaso.user.js
index e15075f9..f880efba 100644
--- a/plugins/bookmarks-by-zaso.user.js
+++ b/plugins/bookmarks-by-zaso.user.js
@@ -2,7 +2,7 @@
 // @id             iitc-plugin-bookmarks@ZasoGD
 // @name           IITC plugin: Bookmarks for maps and portals
 // @category       Controls
-// @version        0.2.7.@@DATETIMEVERSION@@
+// @version        0.2.8.@@DATETIMEVERSION@@
 // @namespace      https://github.com/jonatkins/ingress-intel-total-conversion
 // @updateURL      @@UPDATEURL@@
 // @downloadURL    @@DOWNLOADURL@@
@@ -151,18 +151,11 @@
     }
 
     if(newStatus === 1) {
-      $('#bookmarksBox').show();
-      $('#bkmrksTrigger').hide();
+      $('#bookmarksBox').css('height', 'auto');
+      $('#bkmrksTrigger').css('height', '0');
     } else {
-      $('#bookmarksBox').hide();
-      $('#bkmrksTrigger').show();
-    }
-
-    if(window.plugin.bookmarks.isSmart) {
-      var button = $('#bkmrksTrigger');
-      button.toggleClass('open');
-      if(button.hasClass('open')) { button.text('[-] Bookmarks'); }
-      else{ button.text('[+] Bookmarks'); }
+      $('#bkmrksTrigger').css('height', '64px');
+      $('#bookmarksBox').css('height', '0');
     }
 
     window.plugin.bookmarks.statusBox['show'] = newStatus;
@@ -433,6 +426,11 @@
     }
   }
 
+  window.plugin.bookmarks.deleteMode = function() {
+    $('#bookmarksBox').toggleClass('deleteMode');
+  }
+
+
 /***************************************************************************************************************************************************************/
 
   // Saved the new sort of the folders (in the localStorage)
@@ -489,6 +487,7 @@
       items:"li.bookmarkFolder:not(.othersBookmarks)",
       handle:".bookmarksAnchor",
       placeholder:"sortable-placeholder",
+      helper:'clone', // fix accidental click in firefox
       forcePlaceholderSize:true,
       update:function(event, ui) {
         var typeList = $('#'+ui.item.context.id).parent().parent('.bookmarkList').attr('id');
@@ -501,6 +500,7 @@
       connectWith:".bookmarkList ul ul",
       handle:".bookmarksLink",
       placeholder:"sortable-placeholder",
+      helper:'clone', // fix accidental click in firefox
       forcePlaceholderSize:true,
       update:function(event, ui) {
         var typeList = $('#'+ui.item.context.id).parent().parent().parent().parent('.bookmarkList').attr('id');
@@ -548,17 +548,22 @@
   window.plugin.bookmarks.optPaste = function() {
     var promptAction = prompt('Press CTRL+V to paste it.', '');
     if(promptAction !== null && promptAction !== '') {
-      localStorage[window.plugin.bookmarks.KEY_STORAGE] = promptAction;
-      window.plugin.bookmarks.refreshBkmrks();
-      window.runHooks('pluginBkmrksEdit', {"target": "all", "action": "import"});
-      console.log('BOOKMARKS: reset and imported bookmarks');
-      window.plugin.bookmarks.optAlert('Successful. ');
+      try {
+        localStorage[window.plugin.bookmarks.KEY_STORAGE] = promptAction;
+        window.plugin.bookmarks.refreshBkmrks();
+        window.runHooks('pluginBkmrksEdit', {"target": "all", "action": "import"});
+        console.log('BOOKMARKS: reset and imported bookmarks');
+        window.plugin.bookmarks.optAlert('Successful. ');
+      } catch(e) {
+        console.warn('BOOKMARKS: failed to import data: '+e);
+        window.plugin.bookmarks.optAlert('Import failed ');
+      }
     }
   }
 
   window.plugin.bookmarks.optReset = function() {
-    var promptAction = prompt('All bookmarks will be deleted. Are you sure? [Y/N]', '');
-    if(promptAction !== null && (promptAction === 'Y' || promptAction === 'y')) {
+    var promptAction = confirm('All bookmarks will be deleted. Are you sure?', '');
+    if(promptAction) {
       delete localStorage[window.plugin.bookmarks.KEY_STORAGE];
       window.plugin.bookmarks.createStorage();
       window.plugin.bookmarks.loadStorage();
@@ -618,6 +623,8 @@
     if(latlngs.length >= 2 && latlngs.length <= 3) {
       // TODO: add an API to draw-tools rather than assuming things about it's internals
       var newItem;
+      window.plugin.drawTools.setOptions();
+
       if(latlngs.length == 2) {
         newItem = L.geodesicPolyline(latlngs, window.plugin.drawTools.lineOptions);
       } else {
@@ -885,6 +892,7 @@
                           +''
                           +''
                             +'
Maps
'
@@ -904,6 +912,7 @@
                               +'
+ Folder'
                             +'
Plugin Bookmarks disabled*.
';
diff --git a/plugins/bookmarks-css.css b/plugins/bookmarks-css.css
index 9c160667..a8630974 100644
--- a/plugins/bookmarks-css.css
+++ b/plugins/bookmarks-css.css
@@ -9,13 +9,20 @@
 	line-height:22px;
 	text-indent:0;
 	text-decoration:none;
+	-webkit-box-sizing:border-box;
+	-moz-box-sizing:border-box;
+	box-sizing:border-box;
 }
+
 #bookmarksBox{
 	display:block;
 	position:absolute !important;
 	z-index:4001;
 	top:100px;
 	left:100px;
+	width:231px;
+	height:auto;
+	overflow:hidden;
 }
 #bookmarksBox .addForm,
 #bookmarksBox #bookmarksTypeBar,
@@ -25,33 +32,40 @@
 	color:#fff;
 	font-size:14px;
 }
-#bookmarksBox #topBar,
-#bookmarksBox #topBar *{
+#bookmarksBox #topBar{
 	height:15px !important;
 }
+#bookmarksBox #topBar *{
+	height: 14px !important;
+}
 #bookmarksBox #topBar *{
 	float:left !important;
 }
 #bookmarksBox .handle{
-	text-indent:-20px;
-	width:209px;
+	width:80%;
 	text-align:center;
 	color:#fff;
-	line-height:8px;
+	line-height:6px;
 	cursor:move;
 }
 #bookmarksBox #topBar .btn{
 	display:block;
-	width:19px;
+	width:10%;
 	cursor:pointer;
 	color:#20a8b1;
-}
-#bookmarksBox #topBar #bookmarksMin{
+
 	font-weight:bold;
 	text-align:center;
-	line-height:14px;
+	line-height:13px;
 	font-size:18px;
 }
+
+#bookmarksBox #topBar #bookmarksDel{
+	overflow:hidden;
+	text-indent:-999px;
+	background:#B42E2E;
+}
+
 #bookmarksBox #topBar #bookmarksMin:hover{
 	color:#ffce00;
 }
@@ -59,8 +73,9 @@
 	clear:both;
 }
 #bookmarksBox h5{
-	padding:4px 0;
-	width:114px;
+	padding:4px 0 23px;
+	width:50%;
+	height:93px !important;
 	text-align:center;
 	color:#788;
 }
@@ -73,9 +88,8 @@
 	color:#ffce00;
 	background:rgba(0,0,0,0);
 }
-#bookmarksBox #topBar .btn,
+#bookmarksBox #topBar,
 #bookmarksBox .addForm,
-#bookmarksBox .handle,
 #bookmarksBox #bookmarksTypeBar,
 #bookmarksBox .bookmarkList li.bookmarksEmpty,
 #bookmarksBox .bookmarkList li.bkmrk a,
@@ -90,16 +104,16 @@
 #bookmarksBox .addForm *{
 	display:block;
 	float:left;
-	padding:4px 8px 3px;
+	height:28px !important;
 }
 #bookmarksBox .addForm a{
 	cursor:pointer;
 	color:#20a8b1;
 	font-size:12px;
-	width:65px;
+	width:35%;
 	text-align:center;
 	line-height:20px;
-	padding:4px 0 3px;
+	padding:4px 0 23px;
 }
 #bookmarksBox .addForm a:hover{
 	background:#ffce00;
@@ -109,15 +123,19 @@
 #bookmarksBox .addForm input{
 	font-size:11px !important;
 	color:#ffce00;
-	width:81px;
-	line-height:11px;
+	height:28px;
+	padding:4px 8px 1px;
+	line-height:12px;
 	font-size:12px;
-	-webkit-box-sizing:content-box;
-	-moz-box-sizing:content-box;
-	box-sizing:content-box;
 }
 #bookmarksBox #bkmrk_portals .addForm input{
-	width:147px;
+	width:65%;
+}
+#bookmarksBox #bkmrk_maps .addForm input{
+	width:42%;
+}
+#bookmarksBox #bkmrk_maps .addForm a{
+	width:29%;
 }
 #bookmarksBox .addForm input:hover,
 #bookmarksBox .addForm input:focus{
@@ -125,11 +143,12 @@
 	background:rgba(0,0,0,.6);
 }
 #bookmarksBox .bookmarkList > ul{
-	width:231px;
 	clear:both;
 	list-style-type:none;
 	color:#fff;
 	overflow:hidden;
+	overflow-y:auto;
+	max-height:580px;
 }
 #bookmarksBox .sortable-placeholder{
 	background:rgba(8,48,78,.55);
@@ -161,12 +180,12 @@
 	color:#eee;
 }
 #bookmarksBox ul .bookmarksRemoveFrom{
-	width:19px;
+	width:10%;
 	text-align:center;
 	color:#fff;
 }
 #bookmarksBox ul .bookmarksLink{
-	width:171px;
+	width:90%;
 	padding:0 10px 0 8px;
 	color:#ffce00;
 }
@@ -174,7 +193,7 @@
 	color:#03fe03;
 }
 #bookmarksBox ul .othersBookmarks .bookmarksLink{
-	width:190px;
+	width:90%;
 }
 #bookmarksBox ul .bookmarksLink:hover{
 	color:#03fe03;
@@ -183,6 +202,8 @@
 	color:#fff;
 	background:#e22 !important;
 }
+
+/*---- UI border -----*/
 #bookmarksBox,
 #bookmarksBox *{
 	border-color:#20a8b1;
@@ -193,40 +214,44 @@
 #bookmarksBox ul .bookmarkFolder{
 	border-top-width:1px;
 }
+
 #bookmarksBox #topBar,
 #bookmarksBox #bookmarksTypeBar,
 #bookmarksBox .addForm,
 #bookmarksBox ul .bookmarkFolder .folderLabel,
-#bookmarksBox ul li.bkmrk{
+#bookmarksBox ul li.bkmrk a {
 	border-bottom-width:1px;
 }
-#bookmarksBox ul .bookmarkFolder,
-#bookmarksBox ul .bookmarksRemoveFrom{
+#bookmarksBox ul .bookmarkFolder{
 	border-right-width:1px;
 	border-left-width:1px;
 }
 #bookmarksBox #topBar *,
 #bookmarksBox #bookmarksTypeBar *,
-#bookmarksBox .addForm *{
+#bookmarksBox .addForm *,
+#bookmarksBox ul li.bkmrk{
 	border-left-width:1px;
 }
 #bookmarksBox #topBar,
 #bookmarksBox #bookmarksTypeBar,
-#bookmarksBox .addForm{
+#bookmarksBox .addForm,
+#bookmarksBox ul .bookmarksRemoveFrom{
 	border-right-width:1px;
 }
-#bookmarksBox ul .othersBookmarks .bookmarksRemoveFrom,
+#bookmarksBox ul .bookmarkFolder.othersBookmarks li.bkmrk,
 #bookmarksBox ul .bookmarkFolder .folderLabel .bookmarksRemoveFrom{
 	border-left-width:0;
 }
 #bkmrksTrigger{
-	display:none;
+	display:block !important;
 	position:absolute;
+	overflow:hidden;
 	top:0;
 	left:277px;
 	width:47px;
 	margin-top:-36px;
 	height:64px;
+	height:0;
 	cursor:pointer;
 	z-index:2999;
 	background-position:center bottom;
@@ -272,17 +297,25 @@
 }
 #bookmarksBox .bookmarkList .bkmrk.ui-sortable-helper{
 	border-right-width:1px;
-	border-left-width:1px;
+	border-left-width:1px !important;
 }
 #bookmarksBox .bookmarkList ul li ul li.sortable-placeholder{
 	height:23px;
 	box-shadow:inset 0 -1px 0 #20a8b1,inset 1px 0 0 #20a8b1;
 }
+
 #bookmarksBox .bookmarkList ul li.bookmarkFolder.ui-sortable-helper,
-#bookmarksBox .bookmarkList ul li.othersBookmarks ul,
 #bookmarksBox .bookmarkList ul li.othersBookmarks ul li.sortable-placeholder{
 	box-shadow:inset 0 -1px 0 #20a8b1;
 }
+
+#bookmarksBox #topBar #bookmarksDel,
+#bookmarksBox .bookmarkList .bookmarkFolder .folderLabel:hover .bookmarksRemoveFrom,
+#bookmarksBox .bookmarkList .bookmarkFolder .folderLabel:hover .bookmarksAnchor{
+	border-bottom-width:1px;
+}
+
+/*---------*/
 #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel .bookmarksAnchor span,
 #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel > span,
 #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel > span > span,
@@ -304,7 +337,7 @@
 #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel .bookmarksAnchor{
 	line-height:25px;
 	color:#fff;
-	width:209px;
+	width:90%;
 }
 #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel .bookmarksAnchor span{
 	float:left;
@@ -336,6 +369,7 @@
 #bookmarksBox .bookmarkList .bookmarkFolder.open .folderLabel > span,
 #bookmarksBox .bookmarkList .bookmarkFolder.open .folderLabel > span > span{
 	display:block;
+	display:none;
 }
 #bookmarksBox .bookmarkList .bookmarkFolder.open .folderLabel:hover > span > span{
 	border-color:transparent #036 transparent transparent;
@@ -345,7 +379,7 @@
 }
 #bookmarksBox .bookmarkList .bookmarkFolder ul{
 	display:none;
-	margin-left:19px;
+	margin-left:10%;
 }
 #bookmarksBox .bookmarkList .bookmarkFolder.open ul{
 	display:block;
@@ -355,6 +389,26 @@
 	margin-left:0;
 }
 
+/*---- Width for deleteMode -----*/
+#bookmarksBox .bookmarksRemoveFrom{
+	display:none !important;
+}
+#bookmarksBox.deleteMode .bookmarksRemoveFrom{
+	display:block !important;
+}
+
+#bookmarksBox .bookmarkList .bookmarkFolder .folderLabel .bookmarksAnchor,
+#bookmarksBox ul .bookmarksLink,
+#bookmarksBox ul .othersBookmarks .bookmarksLink{
+	width:100% !important;
+}
+
+#bookmarksBox.deleteMode .bookmarkList .bookmarkFolder .folderLabel .bookmarksAnchor,
+#bookmarksBox.deleteMode ul .bookmarksLink,
+#bookmarksBox.deleteMode ul .othersBookmarks .bookmarksLink{
+	width:90% !important;
+}
+
 /**********************************************
 	MOBILE
 **********************************************/
@@ -367,7 +421,8 @@
 	margin: 0 !important;
 	padding: 0 !important;
 	border: 0 !important;
-	background: transparent !important;;
+	background: transparent !important;
+	overflow:auto !important;
 }
 #bookmarksBox.mobile .bookmarkList ul,
 #bookmarksBox.mobile .bookmarkList ul li,
@@ -380,14 +435,27 @@
 	box-shadow:none !important;
 	border-width:0 !important;
 }
-#bookmarksBox.mobile #topBar{
+#bookmarksBox.mobile #topBar #bookmarksMin,
+#bookmarksBox.mobile #topBar .handle{
 	display:none !important;
 }
+
+#bookmarksBox.mobile #topBar #bookmarksDel{
+	width:100%;
+	height:34px !important;
+	font-size:13px;
+	color:#fff;
+	font-weight:normal;
+	padding-top:11px;
+	text-indent:0;
+}
+
 #bookmarksBox.mobile #bookmarksTypeBar h5{
 	cursor:pointer;
 	text-align:center;
 	float:left;
 	width:50%;
+	height:auto !important;
 	padding:7px 0;
 }
 #bookmarksBox.mobile #bookmarksTypeBar h5.current{
@@ -413,14 +481,14 @@
 #bookmarksBox.mobile .bookmarkList li.bookmarkFolder a.bookmarksRemoveFrom,
 #bookmarksBox.mobile .bookmarkList li.bkmrk a.bookmarksRemoveFrom{
 	box-shadow:inset 0 1px 0 #20a8b1,inset -1px 0 0 #20a8b1 !important;
-	width:15%;
+	width:10%;
 	background:none !important;
 }
 #bookmarksBox.mobile .bookmarkList li.bookmarkFolder a.bookmarksAnchor,
 #bookmarksBox.mobile .bookmarkList li.bkmrk a.bookmarksLink{
 	text-indent:10px;
-	width:85%;
-	height:21px;
+	height:36px;
+	line-height:24px;
 	overflow:hidden;
 }
 #bookmarksBox.mobile .bookmarkList ul li.bookmarkFolder ul{
@@ -428,7 +496,6 @@
 }
 #bookmarksBox.mobile .bookmarkList > ul{
 	border-bottom:1px solid #20a8b1 !important;
-	border-right:1px solid #20a8b1 !important;
 }
 
 #bookmarksBox.mobile .bookmarkList .bookmarkFolder.othersBookmarks  ul{
@@ -440,14 +507,14 @@
 }
 #bookmarksBox.mobile .bookmarkList > ul{
 	max-height:none;
-	width:85% !important;
+/*	width:85% !important;*/
 }
 #bookmarksBox.mobile .bookmarkList li.bookmarkFolder .folderLabel{
 	box-shadow:0 1px 0 #20a8b1 !important;
 }
 #bookmarksBox.mobile .bookmarkList ul li.bookmarkFolder ul{
-	width:85% !important;
-	margin-left:15% !important;
+	width:90% !important;
+	margin-left:10% !important;
 }
 #bookmarksBox.mobile .bookmarkList ul li.bookmarkFolder.othersBookmarks ul{
 	width:100% !important;
@@ -461,7 +528,7 @@
 }
 #bookmarksBox.mobile .addForm,
 #bookmarksBox.mobile .addForm *{
-	height:35px;
+	height:35px !important;
 	padding:0;
 }
 #bookmarksBox.mobile .addForm a{
@@ -469,14 +536,14 @@
 }
 
 #bookmarksBox.mobile .addForm a{
-	width:25% !important;
+/*	width:25% !important;*/
 }
 #bookmarksBox.mobile .addForm input{
-	width:50% !important;
+/*	width:50% !important;*/
 	text-indent:10px;
 }
 #bookmarksBox.mobile #bkmrk_portals .addForm input{
-	width:75% !important;
+/*	width:75% !important;*/
 }
 #bookmarksBox.mobile #bookmarksTypeBar h5,
 #bookmarksBox.mobile .bookmarkList .addForm a{
@@ -530,10 +597,10 @@
 #bookmarksBox.mobile .bookmarkList .bookmarkFolder.open .folderLabel > span > span{
 	display:block !important;
 }
+
 /**********************************************
 	DIALOG BOX
 **********************************************/
-
 /*---- Auto Drawer -----*/
 #bkmrksAutoDrawer,
 #bkmrksAutoDrawer p,
@@ -597,4 +664,4 @@
 	width:96%;
 	height:120px;
 	resize:vertical;
-}
+}
\ No newline at end of file
diff --git a/plugins/fix-googlemap-china-offset.user.js b/plugins/fix-googlemap-china-offset.user.js
new file mode 100644
index 00000000..a25b271a
--- /dev/null
+++ b/plugins/fix-googlemap-china-offset.user.js
@@ -0,0 +1,198 @@
+// ==UserScript==
+// @id             iitc-plugin-fix-googlemap-china-offset@breezewish
+// @name           IITC plugin: Fix Google Map offsets in China
+// @category       Tweaks
+// @version        0.0.1.@@DATETIMEVERSION@@
+// @namespace      https://github.com/jonatkins/ingress-intel-total-conversion
+// @updateURL      @@UPDATEURL@@
+// @downloadURL    @@DOWNLOADURL@@
+// @description    [@@BUILDNAME@@-@@BUILDDATE@@] Show correct Google Map for China user by applying offset tweaks.
+// @include        https://www.ingress.com/intel*
+// @include        http://www.ingress.com/intel*
+// @match          https://www.ingress.com/intel*
+// @match          http://www.ingress.com/intel*
+// @grant          none
+// ==/UserScript==
+
+@@PLUGINSTART@@
+
+// PLUGIN START ////////////////////////////////////////////////////////
+
+// use own namespace for plugin
+window.plugin.fixChinaOffset = {};
+
+// Before understanding how this plugin works, you should know 3 points:
+// 
+//   Point1.
+//     The coordinate system of Ingress is WGS-84.
+//     However, the tiles of Google maps (except satellite map) in China have
+//     offsets (base on GCJ-02 coordinate system) by China policy.
+//     That means, if you request map tiles by giving GCJ-02 position, you
+//     will get the correct map.
+//   
+//   Point2.
+//     Currently there are no easy algorithm to transform from GCJ-02 to WGS-84,
+//     but we can easily transform data from WGS-84 to GCJ-02.
+//   
+//   Point3.
+//     When using Google maps in IITC, the layer structure looks like this:
+//      ----------------------
+//     | Other Leaflet layers |  (Including portals, links, fields, and so on)
+//      ----------------------
+//     |       L.Google       |  (Only for controling)
+//      ----------------------
+//     |   Google Map layer   |  (Generated by Google Map APIs, for rendering maps)
+//      ----------------------
+//     
+//     When users are interacting with L.Google (for example, dragging, zooming),
+//     L.Google will perform the same action on the Google Map layer using Google
+//     Map APIs. 
+// 
+// So, here is the internal of the plugin:
+// 
+// The plugin overwrites behaviours of L.Google. When users are dragging the map,
+// L.Google will pass offseted positions to Google Map APIs (WGS-84 to GCJ-02).
+// So Google Map APIs will render a correct map.
+// 
+// The offset between Google maps and Ingress objects can also be fixed by applying
+// WGS-84 to GCJ-02 transformation on Ingress objects. However we cannot simply know
+// the requesting bounds of Ingress objects because we cannot transform GCJ-02 to
+// WGS-84. As a result, the Ingress objects on maps would be incomplete.
+// 
+// The algorithm of transforming WGS-84 to GCJ-02 comes from:
+// https://on4wp7.codeplex.com/SourceControl/changeset/view/21483#353936
+// There is no official algorithm because it is classified information.
+
+/////////// begin WGS84 to GCJ-02 transformer /////////
+var WGS84transformer = window.plugin.fixChinaOffset.WGS84transformer = function() {};
+// Krasovsky 1940
+// 
+// a = 6378245.0, 1/f = 298.3
+// b = a * (1 - f)
+// ee = (a^2 - b^2) / a^2;
+WGS84transformer.prototype.a = 6378245.0;
+WGS84transformer.prototype.ee = 0.00669342162296594323;
+
+WGS84transformer.prototype.transform = function(wgLat, wgLng) {
+
+  if(this.isOutOfChina(wgLat, wgLng))
+    return {lat: wgLat, lng: wgLng};
+
+  dLat = this.transformLat(wgLng - 105.0, wgLat - 35.0);
+  dLng = this.transformLng(wgLng - 105.0, wgLat - 35.0);
+  radLat = wgLat / 180.0 * Math.PI;
+  magic = Math.sin(radLat);
+  magic = 1 - this.ee * magic * magic;
+  sqrtMagic = Math.sqrt(magic);
+  dLat = (dLat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtMagic) * Math.PI);
+  dLng = (dLng * 180.0) / (this.a / sqrtMagic * Math.cos(radLat) * Math.PI);
+  mgLat = wgLat + dLat;
+  mgLng = wgLng + dLng;
+
+  return {lat: mgLat, lng: mgLng};
+
+};
+
+WGS84transformer.prototype.isOutOfChina = function(lat, lng) {
+  
+  if(lng < 72.004 || lng > 137.8347) return true;
+  if(lat < 0.8293 || lat > 55.8271) return true;
+  
+  return false;
+
+};
+
+WGS84transformer.prototype.transformLat = function(x, y) {
+  
+  var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
+  ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0;
+  ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0 * Math.PI)) * 2.0 / 3.0;
+  ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y * Math.PI / 30.0)) * 2.0 / 3.0;
+  
+  return ret;
+
+};
+
+WGS84transformer.prototype.transformLng = function(x, y) {
+  
+  var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
+  ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0;
+  ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0 * Math.PI)) * 2.0 / 3.0;
+  ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x / 30.0 * Math.PI)) * 2.0 / 3.0;
+  
+  return ret;
+
+};
+/////////// end WGS84 to GCJ-02 transformer /////////
+
+var WGS84toGCJ02 = new WGS84transformer();
+
+/////////// begin overwrited L.Google /////////
+window.plugin.fixChinaOffset.L = {};
+window.plugin.fixChinaOffset.L.Google = {
+  
+  _update: function(e) {
+
+    if(!this._google) return;
+    this._resize();
+
+    var center = e && e.latlng ? e.latlng : this._map.getCenter();
+
+    ///// modified here ///
+    var _center = window.plugin.fixChinaOffset.getLatLng(center, this._type);
+    ///////////////////////
+    
+    this._google.setCenter(_center);
+    this._google.setZoom(this._map.getZoom());
+
+    this._checkZoomLevels();
+
+  },
+
+  _handleZoomAnim: function (e) {
+
+    var center = e.center;
+
+    ///// modified here ///
+    var _center = window.plugin.fixChinaOffset.getLatLng(center, this._type);
+    ///////////////////////
+    
+    this._google.setCenter(_center);
+    this._google.setZoom(e.zoom);
+
+  }
+
+}
+/////////// end overwrited L.Google /////////
+
+window.plugin.fixChinaOffset.getLatLng = function(pos, type) {
+  
+  // No offsets in satellite and hybrid maps  
+  if(type !== 'SATELLITE' && type !== 'HYBRID') {
+    var newPos = WGS84toGCJ02.transform(pos.lat, pos.lng);
+    return new google.maps.LatLng(newPos.lat, newPos.lng);
+  } else {
+    return new google.maps.LatLng(pos.lat, pos.lng);
+  }
+
+};
+
+window.plugin.fixChinaOffset.overwrite = function(dest, src) {
+  
+  for(var key in src) {
+    if(src.hasOwnProperty(key)) {
+      dest[key] = src[key];
+    }
+  }
+
+}
+
+var setup = function() {
+
+  window.plugin.fixChinaOffset.overwrite(L.Google.prototype, window.plugin.fixChinaOffset.L.Google);
+
+}
+
+// PLUGIN END //////////////////////////////////////////////////////////
+
+@@PLUGINEND@@
diff --git a/website/page/faq.php b/website/page/faq.php
index cf706b6b..3c4f1e93 100644
--- a/website/page/faq.php
+++ b/website/page/faq.php
@@ -158,19 +158,17 @@ From here you can remove/disable individual plugins or IITC itself.
 END
 ),
 
-'mobile-plugins' => Array ( "IITC Mobile: Is it possible to add other plugins to IITC Mobile?",
+'mobile-plugins' => Array ( "IITC Mobile: Is it possible to add external plugins to IITC Mobile?",
 <<<'END'
 Yes it is!
 
-- Create a folder named "IITC_Mobile" in your home directory.-
- Inside this folder, create a new folder named "plugins".-
- Copy all your additional plugins to this folder.-
- You should see your plugins listed above the official plugins.+
- Navigate to the IITC Plugins preference screen and click the (+) icon at the top right. You can select the script using a file explorer of your choice.+
- IITCm creates a new folder in your home directory, named "IITC_Mobile". Inside this folder you'll find a "plugins" folder where all external plugins are copied to.
Note:
 - The filename has to end with *.user.js.-
- If you don't know where to find your home directory: Enable dev-mode in the settings and follow the hint.+
- You need a file explorer app installed to add external plugins
END
 ),