diff --git a/src/all/cubari/AndroidManifest.xml b/src/all/cubari/AndroidManifest.xml
new file mode 100644
index 000000000..a28e3cbe3
--- /dev/null
+++ b/src/all/cubari/AndroidManifest.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="eu.kanade.tachiyomi.extension">
+
+    <application>
+        <activity
+            android:name=".all.cubari.CubariUrlActivity"
+            android:excludeFromRecents="true"
+            android:theme="@android:style/Theme.NoDisplay">
+            <!-- We need another intent filter so the /a/..* shortcut -->
+            <!-- doesn't pollute the cubari one, since they work in any combination -->
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+
+                <data
+                    android:host="*cubari.moe"
+                    android:pathPattern="/read/..*"
+                    android:scheme="https" />
+
+                <data
+                    android:host="*cubari.moe"
+                    android:pathPattern="/proxy/..*"
+                    android:scheme="https" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+
+                <data
+                    android:host="*guya.moe"
+                    android:pathPattern="/proxy/..*"
+                    android:scheme="https" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+
+                <data
+                    android:host="*imgur.com"
+                    android:pathPattern="/a/..*"
+                    android:scheme="https" />
+
+                <data
+                    android:host="*imgur.com"
+                    android:pathPattern="/gallery/..*"
+                    android:scheme="https" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
\ No newline at end of file
diff --git a/src/all/cubari/build.gradle b/src/all/cubari/build.gradle
new file mode 100644
index 000000000..afc7c9fd6
--- /dev/null
+++ b/src/all/cubari/build.gradle
@@ -0,0 +1,12 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+
+ext {
+    extName = 'Cubari'
+    pkgNameSuffix = "all.cubari"
+    extClass = '.Cubari'
+    extVersionCode = 1
+    libVersion = '1.2'
+}
+
+apply from: "$rootDir/common.gradle"
diff --git a/src/all/cubari/res/mipmap-hdpi/ic_launcher.png b/src/all/cubari/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..a43b765ef
Binary files /dev/null and b/src/all/cubari/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/src/all/cubari/res/mipmap-mdpi/ic_launcher.png b/src/all/cubari/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..d2a531cfc
Binary files /dev/null and b/src/all/cubari/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/src/all/cubari/res/mipmap-xhdpi/ic_launcher.png b/src/all/cubari/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..b8ce2733b
Binary files /dev/null and b/src/all/cubari/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/src/all/cubari/res/mipmap-xxhdpi/ic_launcher.png b/src/all/cubari/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..804782509
Binary files /dev/null and b/src/all/cubari/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/src/all/cubari/res/mipmap-xxxhdpi/ic_launcher.png b/src/all/cubari/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..84438c81a
Binary files /dev/null and b/src/all/cubari/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/src/all/cubari/res/web_hi_res_512.png b/src/all/cubari/res/web_hi_res_512.png
new file mode 100644
index 000000000..1dfd0c08c
Binary files /dev/null and b/src/all/cubari/res/web_hi_res_512.png differ
diff --git a/src/all/cubari/src/eu/kanade/tachiyomi/extension/all/cubari/Cubari.kt b/src/all/cubari/src/eu/kanade/tachiyomi/extension/all/cubari/Cubari.kt
new file mode 100644
index 000000000..d8e0c4f03
--- /dev/null
+++ b/src/all/cubari/src/eu/kanade/tachiyomi/extension/all/cubari/Cubari.kt
@@ -0,0 +1,353 @@
+package eu.kanade.tachiyomi.extension.all.cubari
+
+import android.os.Build
+import eu.kanade.tachiyomi.extension.BuildConfig
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.network.asObservableSuccess
+import eu.kanade.tachiyomi.source.model.FilterList
+import eu.kanade.tachiyomi.source.model.MangasPage
+import eu.kanade.tachiyomi.source.model.Page
+import eu.kanade.tachiyomi.source.model.SChapter
+import eu.kanade.tachiyomi.source.model.SManga
+import eu.kanade.tachiyomi.source.online.HttpSource
+import okhttp3.Headers
+import okhttp3.Request
+import okhttp3.Response
+import org.json.JSONArray
+import org.json.JSONObject
+import rx.Observable
+
+open class Cubari : HttpSource() {
+
+    final override val name = "Cubari"
+    final override val baseUrl = "https://cubari.moe"
+    final override val supportsLatest = true
+    final override val lang = "all"
+
+    override fun headersBuilder() = Headers.Builder().apply {
+        add(
+            "User-Agent",
+            "(Android ${Build.VERSION.RELEASE}; " +
+                "${Build.MANUFACTURER} ${Build.MODEL}) " +
+                "Tachiyomi/${BuildConfig.VERSION_NAME} " +
+                Build.ID
+        )
+    }
+
+    override fun latestUpdatesRequest(page: Int): Request {
+        return GET("$baseUrl/", headers)
+    }
+
+    override fun fetchLatestUpdates(page: Int): Observable<MangasPage> {
+        return client.newBuilder()
+            .addInterceptor(RemoteStorageUtils.HomeInterceptor())
+            .build()!!
+            .newCall(latestUpdatesRequest(page))
+            .asObservableSuccess()
+            .map { response -> latestUpdatesParse(response) }
+    }
+
+    override fun latestUpdatesParse(response: Response): MangasPage {
+        return parseMangaList(JSONArray(response.body()!!.string()), SortType.UNPINNED)
+    }
+
+    override fun popularMangaRequest(page: Int): Request {
+        return GET("$baseUrl/", headers)
+    }
+
+    override fun fetchPopularManga(page: Int): Observable<MangasPage> {
+        return client.newBuilder()
+            .addInterceptor(RemoteStorageUtils.HomeInterceptor())
+            .build()!!
+            .newCall(popularMangaRequest(page))
+            .asObservableSuccess()
+            .map { response -> popularMangaParse(response) }
+    }
+
+    override fun popularMangaParse(response: Response): MangasPage {
+        return parseMangaList(JSONArray(response.body()!!.string()), SortType.PINNED)
+    }
+
+    override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
+        return client.newCall(chapterListRequest(manga))
+            .asObservableSuccess()
+            .map { response -> mangaDetailsParse(response, manga) }
+    }
+
+    // Called when the series is loaded, or when opening in browser
+    override fun mangaDetailsRequest(manga: SManga): Request {
+        return GET("$baseUrl${manga.url}", headers)
+    }
+
+    override fun mangaDetailsParse(response: Response): SManga {
+        throw Exception("Unused")
+    }
+
+    private fun mangaDetailsParse(response: Response, manga: SManga): SManga {
+        return parseMangaFromApi(JSONObject(response.body()!!.string()), manga)
+    }
+
+    override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
+        return client.newCall(chapterListRequest(manga))
+            .asObservableSuccess()
+            .map { response -> chapterListParse(response, manga) }
+    }
+
+    // Gets the chapter list based on the series being viewed
+    override fun chapterListRequest(manga: SManga): Request {
+        val urlComponents = manga.url.split("/")
+        val source = urlComponents[2]
+        val slug = urlComponents[3]
+
+        return GET("$baseUrl/read/api/$source/series/$slug/", headers)
+    }
+
+    override fun chapterListParse(response: Response): List<SChapter> {
+        throw Exception("Unused")
+    }
+
+    // Called after the request
+    private fun chapterListParse(response: Response, manga: SManga): List<SChapter> {
+        val res = response.body()!!.string()
+        return parseChapterList(res, manga)
+    }
+
+    override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
+        return when {
+            chapter.url.contains("/chapter/") -> {
+                client.newCall(pageListRequest(chapter))
+                    .asObservableSuccess()
+                    .map { response ->
+                        directPageListParse(response)
+                    }
+            }
+            else -> {
+                client.newCall(pageListRequest(chapter))
+                    .asObservableSuccess()
+                    .map { response ->
+                        seriesJsonPageListParse(response, chapter)
+                    }
+            }
+        }
+    }
+
+    override fun pageListRequest(chapter: SChapter): Request {
+        return when {
+            chapter.url.contains("/chapter/") -> {
+                GET("$baseUrl${chapter.url}", headers)
+            }
+            else -> {
+                var url = chapter.url.split("/")
+                val source = url[2]
+                val slug = url[3]
+
+                GET("$baseUrl/read/api/$source/series/$slug/", headers)
+            }
+        }
+    }
+
+    private fun directPageListParse(response: Response): List<Page> {
+        val res = response.body()!!.string()
+        val pages = JSONArray(res)
+        val pageArray = ArrayList<Page>()
+
+        for (i in 0 until pages.length()) {
+            val page = if (pages.optJSONObject(i) != null) {
+                pages.getJSONObject(i).getString("src")
+            } else {
+                pages[i]
+            }
+            pageArray.add(Page(i + 1, "", page.toString()))
+        }
+        return pageArray
+    }
+
+    private fun seriesJsonPageListParse(response: Response, chapter: SChapter): List<Page> {
+        val res = response.body()!!.string()
+        val json = JSONObject(res)
+        val groups = json.getJSONObject("groups")
+        val groupIter = groups.keys()
+        val groupMap = HashMap<String, String>()
+
+        while (groupIter.hasNext()) {
+            val groupKey = groupIter.next()
+            groupMap[groups.getString(groupKey)] = groupKey
+        }
+
+        val chapters = json.getJSONObject("chapters")
+
+        val pages = if (chapters.has(chapter.chapter_number.toString())) {
+            chapters
+                .getJSONObject(chapter.chapter_number.toString())
+                .getJSONObject("groups")
+                .getJSONArray(groupMap[chapter.scanlator])
+        } else {
+            chapters
+                .getJSONObject(chapter.chapter_number.toInt().toString())
+                .getJSONObject("groups")
+                .getJSONArray(groupMap[chapter.scanlator])
+        }
+        val pageArray = ArrayList<Page>()
+        for (i in 0 until pages.length()) {
+            val page = if (pages.optJSONObject(i) != null) {
+                pages.getJSONObject(i).getString("src")
+            } else {
+                pages[i]
+            }
+            pageArray.add(Page(i + 1, "", page.toString()))
+        }
+        return pageArray
+    }
+
+    // Stub
+    override fun pageListParse(response: Response): List<Page> {
+        throw Exception("Unused")
+    }
+
+    override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
+        return when {
+            query.startsWith(PROXY_PREFIX) -> {
+                val trimmedQuery = query.removePrefix(PROXY_PREFIX)
+                // Only tag for recently read on search
+                client.newBuilder()
+                    .addInterceptor(RemoteStorageUtils.TagInterceptor())
+                    .build()!!
+                    .newCall(searchMangaRequest(page, trimmedQuery, filters))
+                    .asObservableSuccess()
+                    .map { response ->
+                        searchMangaParse(response, trimmedQuery)
+                    }
+            }
+            else -> Observable.just(MangasPage(ArrayList(), false))
+        }
+    }
+
+    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+        try {
+            val queryFragments = query.split("/")
+            val source = queryFragments[0]
+            val slug = queryFragments[1]
+
+            return GET("$baseUrl/read/api/$source/series/$slug/", headers)
+        } catch (e: Exception) {
+            throw Exception("Unable to parse. Is your query in the format of ${Cubari.PROXY_PREFIX}<source>/<slug>?")
+        }
+    }
+
+    override fun searchMangaParse(response: Response): MangasPage {
+        throw Exception("Unused")
+    }
+
+    private fun searchMangaParse(response: Response, query: String): MangasPage {
+        return parseSearchList(JSONObject(response.body()!!.string()), query)
+    }
+
+    // ------------- Helpers and whatnot ---------------
+
+    private fun parseChapterList(payload: String, manga: SManga): List<SChapter> {
+        val json = JSONObject(payload)
+        val groups = json.getJSONObject("groups")
+        val chapters = json.getJSONObject("chapters")
+
+        val chapterList = ArrayList<SChapter>()
+
+        val iter = chapters.keys()
+
+        while (iter.hasNext()) {
+            val chapterNum = iter.next()
+            val chapterObj = chapters.getJSONObject(chapterNum)
+            val chapterGroups = chapterObj.getJSONObject("groups")
+            val groupsIter = chapterGroups.keys()
+
+            while (groupsIter.hasNext()) {
+                val groupNum = groupsIter.next()
+                val chapter = SChapter.create()
+
+                chapter.scanlator = groups.getString(groupNum)
+                if (chapterObj.has("release_date")) {
+                    chapter.date_upload =
+                        chapterObj.getJSONObject("release_date").getLong(groupNum) * 1000
+                }
+                chapter.name = chapterNum + " - " + chapterObj.getString("title")
+                chapter.chapter_number = chapterNum.toFloat()
+                chapter.url =
+                    if (chapterGroups.optJSONArray(groupNum) != null) {
+                        "${manga.url}/$chapterNum/$groupNum"
+                    } else {
+                        chapterGroups.getString(groupNum)
+                    }
+                chapterList.add(chapter)
+            }
+        }
+
+        return chapterList.reversed()
+    }
+
+    private fun parseMangaList(payload: JSONArray, sortType: SortType): MangasPage {
+        val mangas = ArrayList<SManga>()
+
+        for (i in 0 until payload.length()) {
+            val json = payload.getJSONObject(i)
+            val pinned = json.getBoolean("pinned")
+
+            if (sortType == SortType.PINNED && pinned) {
+                mangas.add(parseMangaFromRemoteStorage(json))
+            } else if (sortType == SortType.UNPINNED && !pinned) {
+                mangas.add(parseMangaFromRemoteStorage(json))
+            }
+        }
+
+        return MangasPage(mangas, false)
+    }
+
+    private fun parseSearchList(payload: JSONObject, query: String): MangasPage {
+        val mangas = ArrayList<SManga>()
+        val tempManga = SManga.create()
+        tempManga.url = "/read/$query"
+        mangas.add(parseMangaFromApi(payload, tempManga))
+        return MangasPage(mangas, false)
+    }
+
+    private fun parseMangaFromRemoteStorage(json: JSONObject): SManga {
+        val manga = SManga.create()
+        manga.title = json.getString("title")
+        manga.artist = json.optString("artist", ARTIST_FALLBACK)
+        manga.author = json.optString("author", AUTHOR_FALLBACK)
+        manga.description = json.optString("description", DESCRIPTION_FALLBACK)
+        manga.url = json.getString("url")
+        manga.thumbnail_url = json.getString("coverUrl")
+
+        return manga
+    }
+
+    private fun parseMangaFromApi(json: JSONObject, mangaReference: SManga): SManga {
+        val manga = SManga.create()
+        manga.title = json.getString("title")
+        manga.artist = json.optString("artist", ARTIST_FALLBACK)
+        manga.author = json.optString("author", AUTHOR_FALLBACK)
+        manga.description = json.optString("description", DESCRIPTION_FALLBACK)
+        manga.url = mangaReference.url
+        manga.thumbnail_url = json.optString("cover", "")
+
+        return manga
+    }
+
+    // ----------------- Things we aren't supporting -----------------
+
+    override fun imageUrlParse(response: Response): String {
+        throw Exception("imageUrlParse not supported.")
+    }
+
+    companion object {
+        const val PROXY_PREFIX = "cubari:"
+
+        const val AUTHOR_FALLBACK = "Unknown"
+        const val ARTIST_FALLBACK = "Unknown"
+        const val DESCRIPTION_FALLBACK = "No description."
+
+        enum class SortType {
+            PINNED,
+            UNPINNED
+        }
+    }
+}
diff --git a/src/all/cubari/src/eu/kanade/tachiyomi/extension/all/cubari/CubariUrlActivity.kt b/src/all/cubari/src/eu/kanade/tachiyomi/extension/all/cubari/CubariUrlActivity.kt
new file mode 100644
index 000000000..4d06f04e9
--- /dev/null
+++ b/src/all/cubari/src/eu/kanade/tachiyomi/extension/all/cubari/CubariUrlActivity.kt
@@ -0,0 +1,64 @@
+package eu.kanade.tachiyomi.extension.all.cubari
+
+import android.app.Activity
+import android.content.ActivityNotFoundException
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import kotlin.system.exitProcess
+
+class CubariUrlActivity : Activity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        val host = intent?.data?.host
+        val pathSegments = intent?.data?.pathSegments
+
+        if (host != null && pathSegments != null) {
+            val query = when (host) {
+                "m.imgur.com", "imgur.com" -> fromImgur(pathSegments)
+                else -> fromCubari(pathSegments)
+            }
+
+            if (query == null) {
+                Log.e("CubariUrlActivity", "Unable to parse URI from intent $intent")
+                finish()
+                exitProcess(1)
+            }
+
+            val mainIntent = Intent().apply {
+                action = "eu.kanade.tachiyomi.SEARCH"
+                putExtra("query", query)
+                putExtra("filter", packageName)
+            }
+
+            try {
+                startActivity(mainIntent)
+            } catch (e: ActivityNotFoundException) {
+                Log.e("CubariUrlActivity", e.toString())
+            }
+        }
+
+        finish()
+        exitProcess(0)
+    }
+
+    private fun fromImgur(pathSegments: List<String>): String? {
+        if (pathSegments.size >= 2) {
+            val id = pathSegments[1]
+
+            return "${Cubari.PROXY_PREFIX}imgur/$id"
+        }
+        return null
+    }
+
+    private fun fromCubari(pathSegments: MutableList<String>): String? {
+        return if (pathSegments.size >= 3) {
+            val source = pathSegments[1]
+            val slug = pathSegments[2]
+            "${Cubari.PROXY_PREFIX}$source/$slug"
+        } else {
+            null
+        }
+    }
+}
diff --git a/src/all/cubari/src/eu/kanade/tachiyomi/extension/all/cubari/RemoteStorageUtils.kt b/src/all/cubari/src/eu/kanade/tachiyomi/extension/all/cubari/RemoteStorageUtils.kt
new file mode 100644
index 000000000..3e4fbd060
--- /dev/null
+++ b/src/all/cubari/src/eu/kanade/tachiyomi/extension/all/cubari/RemoteStorageUtils.kt
@@ -0,0 +1,147 @@
+package eu.kanade.tachiyomi.extension.all.cubari
+
+import android.annotation.SuppressLint
+import android.app.Application
+import android.os.Handler
+import android.os.Looper
+import android.webkit.JavascriptInterface
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import okhttp3.Interceptor
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.ResponseBody
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
+import java.io.IOException
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+class RemoteStorageUtils {
+    abstract class GenericInterceptor(private val transparent: Boolean) : Interceptor {
+        private val handler = Handler(Looper.getMainLooper())
+
+        abstract val jsScript: String
+
+        abstract fun urlModifier(originalUrl: String): String
+
+        internal class JsInterface(private val latch: CountDownLatch, var payload: String = "") {
+            @JavascriptInterface
+            fun passPayload(passedPayload: String) {
+                payload = passedPayload
+                latch.countDown()
+            }
+        }
+
+        @Synchronized
+        override fun intercept(chain: Interceptor.Chain): Response {
+            try {
+                val originalRequest = chain.request()
+                val originalResponse = chain.proceed(originalRequest)
+                return proceedWithWebView(originalRequest, originalResponse)
+            } catch (e: Exception) {
+                throw IOException(e)
+            }
+        }
+
+        @SuppressLint("SetJavaScriptEnabled", "AddJavascriptInterface")
+        private fun proceedWithWebView(request: Request, response: Response): Response {
+            val latch = CountDownLatch(1)
+
+            var webView: WebView? = null
+
+            val origRequestUrl = request.url().toString()
+            val headers = request.headers().toMultimap().mapValues {
+                it.value.getOrNull(0) ?: ""
+            }.toMutableMap()
+            val jsInterface = JsInterface(latch)
+
+            handler.post {
+                val webview = WebView(Injekt.get<Application>())
+                webView = webview
+                with(webview.settings) {
+                    javaScriptEnabled = true
+                    domStorageEnabled = true
+                    databaseEnabled = true
+                    useWideViewPort = false
+                    loadWithOverviewMode = false
+                    userAgentString = request.header("User-Agent")
+                }
+
+                webview.addJavascriptInterface(jsInterface, "android")
+
+                webview.webViewClient = object : WebViewClient() {
+                    override fun onPageFinished(view: WebView, url: String) {
+                        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
+                            view.evaluateJavascript(jsScript) {}
+                        }
+                        if (transparent) {
+                            latch.countDown()
+                        }
+                    }
+                }
+
+                webview.loadUrl(urlModifier(origRequestUrl), headers)
+            }
+
+            latch.await(TIMEOUT_SEC, TimeUnit.SECONDS)
+
+            handler.postDelayed(
+                { webView?.destroy() },
+                DELAY_MILLIS * (if (transparent) 2 else 1)
+            )
+
+            return if (transparent) {
+                response
+            } else {
+                response.newBuilder().body(ResponseBody.create(response.body()?.contentType(), jsInterface.payload)).build()
+            }
+        }
+    }
+
+    class TagInterceptor : GenericInterceptor(true) {
+        override val jsScript: String = """
+           let dispatched = false;
+           window.addEventListener('history-ready', function () {
+             if (!dispatched) {
+               dispatched = true;
+               Promise.all(
+                 [globalHistoryHandler.getAllPinnedSeries(), globalHistoryHandler.getAllUnpinnedSeries()]
+               ).then(e => {
+                 window.android.passPayload(JSON.stringify(e.flatMap(e => e)))
+               });
+             }
+           });
+           tag();
+        """
+
+        override fun urlModifier(originalUrl: String): String {
+            return originalUrl.replace("/api/", "/").replace("/series/", "/")
+        }
+    }
+
+    class HomeInterceptor : GenericInterceptor(false) {
+        override val jsScript: String = """
+           let dispatched = false;
+           (function () {
+             if (!dispatched) {
+               dispatched = true;
+               Promise.all(
+                 [globalHistoryHandler.getAllPinnedSeries(), globalHistoryHandler.getAllUnpinnedSeries()]
+               ).then(e => {
+                 window.android.passPayload(JSON.stringify(e.flatMap(e => e) ) )
+               });
+             }
+           })();
+        """
+
+        override fun urlModifier(originalUrl: String): String {
+            return originalUrl
+        }
+    }
+
+    companion object {
+        const val TIMEOUT_SEC: Long = 10
+        const val DELAY_MILLIS: Long = 10000
+    }
+}