<NME> MapDownloaderElevate.java
<BEF> ADDFILE
<MSG> support downloading map theme files

<DFF> @@ -0,0 +1,68 @@
+package cgeo.geocaching.settings;
+
+import cgeo.geocaching.CgeoApplication;
+import cgeo.geocaching.R;
+import cgeo.geocaching.models.OfflineMap;
+import cgeo.geocaching.storage.PersistableFolder;
+import cgeo.geocaching.utils.MatcherWrapper;
+
+import android.net.Uri;
+
+import androidx.annotation.NonNull;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+public class MapDownloaderElevate extends AbstractDownloader {
+
+    private static final Pattern PATTERN_LAST_UPDATED_DATE = Pattern.compile("<a href=\"https:\\/\\/www\\.openandromaps\\.org\\/wp-content\\/users\\/tobias\\/version\\.txt\">[0-9]\\.[0-9]\\.[0-9]<\\/a><\\/strong>, ([0-9]{1,2})\\.([0-9]{1,2})\\.([0-9]{2}) ");
+
+    private MapDownloaderElevate() {
+        super(OfflineMap.OfflineMapType.MAP_DOWNLOAD_TYPE_ELEVATE, R.string.mapserver_elevate_updatecheckurl, R.string.mapserver_elevate_name, R.string.mapserver_elevate_info, R.string.mapserver_openandromaps_projecturl, R.string.mapserver_openandromaps_likeiturl, PersistableFolder.OFFLINE_MAP_THEMES);
+        this.forceExtension = ".zip";
+    }
+
+    @Override
+    protected void analyzePage(final Uri uri, final List<OfflineMap> list, final String page) {
+        final OfflineMap file = checkUpdateFor(page, CgeoApplication.getInstance().getString(R.string.mapserver_elevate_downloadurl), "Elevate.zip");
+        if (file != null) {
+            list.add(file);
+        }
+    }
+
+    @Override
+    protected OfflineMap checkUpdateFor(final String page, final String remoteUrl, final String remoteFilename) {
+        final MatcherWrapper matchDate = new MatcherWrapper(PATTERN_LAST_UPDATED_DATE, page);
+        if (matchDate.find()) {
+            final String date = "20" + matchDate.group(3) + "-" + matchDate.group(2) + "-" + matchDate.group(1);
+            return new OfflineMap("Elevate", Uri.parse(CgeoApplication.getInstance().getString(R.string.mapserver_elevate_downloadurl) + "Elevate.zip"), false, date, "", offlineMapType);
+        }
+        return null;
+    }
+
+    // elevate uses different servers for update check and download, need to map here
+    @Override
+    protected String getUpdatePageUrl(final String downloadPageUrl) {
+        final String compare = downloadPageUrl.endsWith("/") ? downloadPageUrl : downloadPageUrl + "/";
+        final String downloadUrl = CgeoApplication.getInstance().getString(R.string.mapserver_elevate_downloadurl);
+        final String updateUrl = CgeoApplication.getInstance().getString(R.string.mapserver_elevate_updatecheckurl);
+        if (compare.startsWith(downloadUrl)) {
+            final String result = updateUrl + compare.substring(downloadUrl.length());
+            return result.endsWith("/") ? result : result + "/";
+        }
+        return downloadPageUrl;
+    }
+
+    @NonNull
+    public static MapDownloaderElevate getInstance() {
+        return MapDownloaderElevate.Holder.INSTANCE;
+    }
+
+    /**
+     * initialization on demand holder pattern
+     */
+    private static class Holder {
+        @NonNull
+        private static final MapDownloaderElevate INSTANCE = new MapDownloaderElevate();
+    }
+}

support downloading map theme files