[
  {
    "path": ".gitignore",
    "content": "# built application files\n*.apk\n*.ap_\n\n# files for the dex VM\n*.dex\n\n# Java class files\n*.class\n\n# generated files\nbin/\ngen/\nout/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Eclipse project files\n.classpath\n.project\n\n# Android Studio\n.idea/\n.gradle\nbuild/\n/*/local.properties\nlocal.properties\n/*/out\n/*/*/build\n/*/*/production\n*.iml\n*.iws\n*.ipr\n*~\n*.swp\nproguard/\n*.log\n.navigation/\ncaptures/\n\n# Keystore files\n*.jks\n\n# Android SDK\n/android-sdk.zip\n/android-studio\n"
  },
  {
    "path": "LICENSE.md",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2017 Nicholas Rout\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "# Lens Launcher\n\nLens Launcher is a unique, efficient way to browse and launch your apps.\n\n![Alt text](resources/art/lens_launcher_demo.gif?raw=true \"Title\")\n\nInstead of scrolling long lists or swiping through multiple pages, Lens Launcher implements two unique features:\n\n<b>• An Equispaced Grid that displays all of your apps, regardless of screen size or app count.</b>\n\n<b>• A Graphical Fisheye Lens to quickly zoom, pan and launch apps using touch gestures.</b>\n\nLens Launcher also includes a full Settings menu to tweak all aspects of the Lens; Distortion, Scaling, Icon Size, Haptic Feedback, etc.\n\nThe Graphical Fisheye Lens algorithm is derived from methods proposed by Manojit Sarkar and Marc H. Brown. Their original 1993 paper, titled <i>Graphical Fisheye Views</i>, can be found here:\nhttps://drive.google.com/open?id=0B6Nqy9y098RLa2pqNVFUcUhIZXM\n\nMajor contributions to Lens Launcher have been made by Rish Bhardwaj (@CreaRo)\n\nYou can download Lens Launcher on Google Play:\nhttps://play.google.com/store/apps/details?id=nickrout.lenslauncher\n\n## Build from Source\n\nIf you'd like to build from source, you may do so easily with [Docker][1], but\nif you are wanting to contribute it may be better to install the build tools on\nyour machine.\n\n### Easy Way\n\nBuilding the APK is extremely easy using [`docker-compose`][2], all that is\nneeded is to run the following inside the repo's directory:\n\n```bash\ndocker-compose run --rm gradle\n```\n\nThen download the APK inside\n`lens-launcher/app/build/outputs/apk/app-release.apk` to your phone to install.\n\n### For Development\n\n1.  Install the latest Android SDK from [Android Studio][3] and accept the\n    licenses.\n2.  Install Java JDK 8 from [Oracle][4].\n3.  Run `keytool` and create a keystore following the command prompts.\n4.  Generate an APK with `gradlew` like below:\n\n    ```bash\n    gradlew assembleRelease \\\n      -Pandroid.injected.signing.key.alias=$KEY_ALIAS \\\n      -Pandroid.injected.signing.store.file=$KEY_STORE_PATH \\\n      -Pandroid.injected.signing.store.password=$KEY_STORE_PASSWORD \\\n      -Pandroid.injected.signing.key.password=$KEY_PASSWORD;\n    ```\n\n[1]: https://docs.docker.com/\n[2]: https://docs.docker.com/compose/install/\n[3]: https://developer.android.com/studio/index.html\n[4]: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    namespace \"nickrout.lenslauncher\"\n    compileSdk 34\n    defaultConfig {\n        applicationId \"nickrout.lenslauncher\"\n        minSdkVersion 15\n        targetSdkVersion 34\n        versionCode 46\n        versionName \"3.0.1\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    testImplementation 'junit:junit:4.13.2'\n    implementation 'com.android.support:appcompat-v7:26.1.0'\n    implementation 'com.android.support:design:26.1.0'\n    implementation 'com.android.support:recyclerview-v7:26.1.0'\n    implementation 'com.android.support:cardview-v7:26.1.0'\n    implementation 'com.android.support:palette-v7:26.1.0'\n    implementation 'com.github.satyan:sugar:1.5'\n    implementation 'com.afollestad.material-dialogs:core:0.9.5.0'\n    implementation 'com.afollestad.material-dialogs:commons:0.9.5.0'\n    implementation 'com.jakewharton:butterknife:8.8.1'\n    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'\n}\n\ntasks.withType(JavaCompile).configureEach{\n    options.fork = true\n    options.forkOptions.jvmArgs +=[\n            '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',\n            '--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',\n            '--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED']\n}\n"
  },
  {
    "path": "app/build.gradle.orig",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 23\n    buildToolsVersion \"23.0.3\"\n\n    defaultConfig {\n        applicationId \"nickrout.lenslauncher\"\n        minSdkVersion 16\n        targetSdkVersion 23\n        versionCode 16\n        versionName \"1.3.0\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    testCompile 'junit:junit:4.12'\n    compile 'com.android.support:appcompat-v7:23.4.0'\n<<<<<<< HEAD\n    compile 'com.android.support:design:23.1.1'\n    compile 'com.android.support:recyclerview-v7:23.3.0'\n    compile 'com.android.support:cardview-v7:23.3.0'\n=======\n    compile 'com.android.support:palette-v7:23.4.0'\n>>>>>>> 85209e8a5dc31e126a1f49a543f70d299720c052\n    compile 'com.github.satyan:sugar:1.5'\n    compile 'com.afollestad.material-dialogs:core:0.8.5.8'\n    compile 'com.afollestad.material-dialogs:commons:0.8.5.8'\n    compile 'com.makeramen:dragsortadapter:1.3.0'\n    compile 'com.jakewharton:butterknife:7.0.1'\n}\n"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/nicholasrout/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n"
  },
  {
    "path": "app/src/androidTest/java/nickrout/lenslauncher/ApplicationTest.java",
    "content": "package nickrout.lenslauncher;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http://d.android.com/tools/testing/testing_android.html\">Testing Fundamentals</a>\n */\npublic class ApplicationTest extends ApplicationTestCase<Application> {\n    public ApplicationTest() {\n        super(Application.class);\n    }\n}"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"nickrout.lenslauncher\">\n    \n    <uses-permission android:name=\"QUERY_ALL_PACKAGES\" />\n\n    <queries>\n        <intent>\n            <action android:name=\"android.intent.action.MAIN\" />\n        </intent>\n    </queries>\n\n    <application\n        android:name=\".LensLauncherApplication\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:roundIcon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:largeHeap=\"true\"\n        android:theme=\"@style/AppTheme\"\n        android:supportsRtl=\"true\">\n\n        <meta-data\n            android:name=\"DATABASE\"\n            android:value=\"app_persistent.db\" />\n        <meta-data\n            android:name=\"VERSION\"\n            android:value=\"7\" />\n        <meta-data\n            android:name=\"QUERY_LOG\"\n            android:value=\"false\" />\n        <meta-data\n            android:name=\"DOMAIN_PACKAGE_NAME\"\n            android:value=\"nickrout.lenslauncher.model\" />\n\n        <activity\n            android:name=\".ui.HomeActivity\"\n            android:launchMode=\"singleTask\"\n            android:stateNotNeeded=\"true\"\n            android:taskAffinity=\"\"\n            android:theme=\"@style/HomeTheme\"\n            android:exported=\"true\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.HOME\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n            </intent-filter>\n        </activity>\n\n        <activity\n            android:name=\".ui.SettingsActivity\"\n            android:launchMode=\"singleTask\"\n            android:stateNotNeeded=\"true\"\n            android:taskAffinity=\"\"\n            android:theme=\"@style/AppTheme.NoActionBar\"\n            android:exported=\"true\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n            <meta-data\n                android:name=\"android.app.shortcuts\"\n                android:resource=\"@xml/shortcuts\" />\n        </activity>\n\n        <activity\n            android:name=\".ui.AboutActivity\"\n            android:label=\"@string/activity_title_about\"\n            android:theme=\"@style/AppTheme.NoActionBar\">\n        </activity>\n\n        <activity\n            android:name=\".ui.FakeLauncherActivity\"\n            android:enabled=\"false\"\n            android:exported=\"false\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.HOME\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n            </intent-filter>\n        </activity>\n\n        <receiver\n            android:name=\".background.BroadcastReceivers$AppsUpdatedReceiver\"\n            android:exported=\"false\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.PACKAGE_ADDED\" />\n                <action android:name=\"android.intent.action.PACKAGE_REMOVED\" />\n                <action android:name=\"android.intent.action.PACKAGE_CHANGED\" />\n                <action android:name=\"android.intent.action.PACKAGE_REPLACED\" />\n                <data android:scheme=\"package\" />\n            </intent-filter>\n        </receiver>\n\n        <receiver android:name=\".background.BroadcastReceivers$AppsEditedReceiver\">\n        </receiver>\n\n        <receiver android:name=\".background.BroadcastReceivers$AppsVisibilityChangedReceiver\">\n        </receiver>\n\n        <receiver android:name=\".background.BroadcastReceivers$AppsLoadedReceiver\">\n        </receiver>\n\n        <receiver android:name=\".background.BroadcastReceivers$BackgroundChangedReceiver\">\n        </receiver>\n\n        <receiver android:name=\".background.BroadcastReceivers$NightModeReceiver\">\n        </receiver>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "app/src/main/AndroidManifest.xml.orig",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"nickrout.lenslauncher\">\n\n    <application\n        android:name=\"com.orm.SugarApp\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n\n        <meta-data\n            android:name=\"DATABASE\"\n            android:value=\"app_persistent.db\" />\n        <meta-data\n            android:name=\"VERSION\"\n<<<<<<< HEAD\n            android:value=\"2\" />\n=======\n            android:value=\"3\" />\n>>>>>>> 0c9969d213bbd5efac04492932bd13b6d97bacc0\n        <meta-data\n            android:name=\"QUERY_LOG\"\n            android:value=\"false\" />\n        <meta-data\n            android:name=\"DOMAIN_PACKAGE_NAME\"\n            android:value=\"nickrout.lenslauncher.model\" />\n\n        <activity\n            android:name=\".ui.HomeActivity\"\n            android:label=\"@string/app_name\"\n            android:launchMode=\"singleTask\"\n            android:screenOrientation=\"portrait\"\n            android:stateNotNeeded=\"true\"\n            android:theme=\"@style/HomeTheme\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.HOME\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n            </intent-filter>\n        </activity>\n\n        <receiver android:name=\".ui.HomeActivity$AppsUpdatedReceiver\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.PACKAGE_ADDED\" />\n                <action android:name=\"android.intent.action.PACKAGE_REMOVED\" />\n                <action android:name=\"android.intent.action.PACKAGE_CHANGED\" />\n                <action android:name=\"android.intent.action.PACKAGE_REPLACED\" />\n\n                <data android:scheme=\"package\" />\n            </intent-filter>\n        </receiver>\n\n        <activity\n            android:name=\".ui.SettingsActivity\"\n            android:label=\"@string/app_name\"\n            android:screenOrientation=\"portrait\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n        <activity\n            android:name=\".ui.AboutActivity\"\n            android:label=\"@string/activity_title_about\"\n            android:screenOrientation=\"portrait\">\n        </activity>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/AppsSingleton.java",
    "content": "package nickrout.lenslauncher;\n\nimport android.graphics.Bitmap;\n\nimport java.util.ArrayList;\nimport nickrout.lenslauncher.model.App;\n\n/**\n * Created by nicholasrout on 2016/05/30.\n */\npublic class AppsSingleton {\n\n    private static AppsSingleton mAppsSingleton;\n\n    private ArrayList<App> mApps;\n    private ArrayList<Bitmap> mAppIcons;\n\n    private AppsSingleton() {}\n\n    public static AppsSingleton getInstance() {\n        if (mAppsSingleton == null) {\n            mAppsSingleton = new AppsSingleton();\n        }\n        return mAppsSingleton;\n    }\n\n    public ArrayList<App> getApps() {\n        ArrayList<App> apps = new ArrayList<>();\n        if (mApps == null) {\n            return apps;\n        }\n        apps.addAll(mApps);\n        return apps;\n    }\n\n    public void setApps(ArrayList<App> apps) {\n        mApps = apps;\n    }\n\n    public ArrayList<Bitmap> getAppIcons() {\n        ArrayList<Bitmap> appIcons = new ArrayList<>();\n        if (mAppIcons == null) {\n            return appIcons;\n        }\n        appIcons.addAll(mAppIcons);\n        return appIcons;\n    }\n\n    public void setAppIcons(ArrayList<Bitmap> appIcons) {\n        mAppIcons = appIcons;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/LensLauncherApplication.java",
    "content": "package nickrout.lenslauncher;\n\nimport com.orm.SugarApp;\n\nimport java.util.Observable;\nimport java.util.Observer;\n\nimport nickrout.lenslauncher.background.SortAppsTask;\nimport nickrout.lenslauncher.background.EditedObservable;\nimport nickrout.lenslauncher.background.UpdatedObservable;\nimport nickrout.lenslauncher.background.UpdateAppsTask;\n\n/**\n * Created by nicholasrout on 2016/06/12.\n */\npublic class LensLauncherApplication extends SugarApp implements Observer {\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        UpdatedObservable.getInstance().addObserver(this);\n        EditedObservable.getInstance().addObserver(this);\n        updateApps();\n    }\n\n    @Override\n    public void update(Observable observable, Object data) {\n        if (observable instanceof UpdatedObservable) {\n            updateApps();\n        } else if (observable instanceof EditedObservable) {\n            editApps();\n        }\n    }\n\n    private void updateApps() {\n        new UpdateAppsTask(\n                getPackageManager(),\n                getApplicationContext(),\n                this)\n                .execute();\n    }\n\n    private void editApps() {\n        new SortAppsTask(\n                getApplicationContext(),\n                this)\n                .execute();\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/adapter/AppRecyclerAdapter.java",
    "content": "package nickrout.lenslauncher.adapter;\n\nimport android.content.ActivityNotFoundException;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.graphics.Rect;\nimport android.net.Uri;\nimport android.provider.Settings;\nimport android.support.design.widget.Snackbar;\nimport android.support.v7.widget.CardView;\nimport android.support.v7.widget.PopupMenu;\nimport android.support.v7.widget.RecyclerView;\nimport android.view.LayoutInflater;\nimport android.view.MenuItem;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ImageView;\nimport android.widget.TextView;\nimport android.widget.Toast;\n\nimport java.util.List;\n\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport nickrout.lenslauncher.R;\nimport nickrout.lenslauncher.background.BroadcastReceivers;\nimport nickrout.lenslauncher.model.App;\nimport nickrout.lenslauncher.model.AppPersistent;\nimport nickrout.lenslauncher.ui.SettingsActivity;\nimport nickrout.lenslauncher.util.AppUtil;\n\npublic class AppRecyclerAdapter extends RecyclerView.Adapter {\n\n    public static final String TAG = \"AppRecyclerAdapter\";\n\n    private Context mContext;\n    private final List<App> mApps;\n\n    public AppRecyclerAdapter(Context mContext, List<App> mApps) {\n        this.mContext = mContext;\n        this.mApps = mApps;\n    }\n\n    public App getItemForPosition(int position) {\n        return mApps.get(position);\n    }\n\n    @Override\n    public int getItemCount() {\n        return mApps.size();\n    }\n\n    @Override\n    public long getItemId(int position) {\n        return mApps.get(position).getId();\n    }\n\n    @Override\n    public AppViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n        LayoutInflater inflater = LayoutInflater.from(parent.getContext());\n        View view = inflater.inflate(R.layout.recycler_item_app, parent, false);\n        final AppViewHolder holder = new AppViewHolder(view, mContext);\n        holder.setOnClickListeners();\n        return holder;\n    }\n\n    @Override\n    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {\n        App app = getItemForPosition(position);\n        if (app == null) {\n            return;\n        }\n        AppViewHolder appViewHolder = (AppViewHolder) holder;\n        appViewHolder.setAppElement(app);\n    }\n\n    public static class AppViewHolder extends RecyclerView.ViewHolder implements PopupMenu.OnMenuItemClickListener {\n\n        @BindView(R.id.element_app_container)\n        CardView mContainer;\n\n        @BindView(R.id.element_app_label)\n        TextView mLabel;\n\n        @BindView(R.id.element_app_icon)\n        ImageView mIcon;\n\n        @BindView(R.id.element_app_hide)\n        ImageView mToggleAppVisibility;\n\n        @BindView(R.id.element_app_menu)\n        ImageView mMenu;\n\n        private App mApp;\n        private Context mContext;\n\n        public AppViewHolder(View itemView, Context context) {\n            super(itemView);\n            ButterKnife.bind(this, itemView);\n            this.mContext = context;\n        }\n\n        public void setAppElement(App app) {\n            this.mApp = app;\n            mLabel.setText(mApp.getLabel());\n            mIcon.setImageBitmap(mApp.getIcon());\n            boolean isAppVisible =\n                    AppPersistent.getAppVisibility(mApp.getPackageName().toString(), mApp.getName().toString());\n            if (isAppVisible) {\n                mToggleAppVisibility.setImageResource(R.drawable.ic_visibility_grey_24dp);\n            } else {\n                mToggleAppVisibility.setImageResource(R.drawable.ic_visibility_off_grey_24dp);\n            }\n            if (mApp.getPackageName().toString().equals(\"nickrout.lenslauncher\")) {\n                mToggleAppVisibility.setVisibility(View.INVISIBLE);\n            } else {\n                mToggleAppVisibility.setVisibility(View.VISIBLE);\n            }\n        }\n\n        public void toggleAppVisibility(App app) {\n            this.mApp = app;\n            boolean isAppVisible =\n                    AppPersistent.getAppVisibility(mApp.getPackageName().toString(), mApp.getName().toString());\n            AppPersistent.setAppVisibility(\n                    mApp.getPackageName().toString(),\n                    mApp.getName().toString(),\n                    !isAppVisible);\n            if (isAppVisible) {\n                Snackbar.make(mContainer, mApp.getLabel() + \" is now hidden\", Snackbar.LENGTH_LONG).show();\n                mToggleAppVisibility.setImageResource(R.drawable.ic_visibility_off_grey_24dp);\n            } else {\n                Snackbar.make(mContainer, mApp.getLabel() + \" is now visible\", Snackbar.LENGTH_LONG).show();\n                mToggleAppVisibility.setImageResource(R.drawable.ic_visibility_grey_24dp);\n            }\n        }\n\n        private void sendChangeAppsVisibilityBroadcast() {\n            if (mContext == null) {\n                return;\n            }\n            if (!(mContext instanceof SettingsActivity)) {\n                return;\n            }\n            SettingsActivity settingsActivity = (SettingsActivity) mContext;\n            Intent changeAppsVisibilityIntent = new Intent(settingsActivity, BroadcastReceivers.AppsVisibilityChangedReceiver.class);\n            settingsActivity.sendBroadcast(changeAppsVisibilityIntent);\n        }\n\n        public void setOnClickListeners() {\n            itemView.setOnClickListener(new View.OnClickListener() {\n                @Override\n                public void onClick(View view) {\n                    AppUtil.launchComponent(\n                            mContext,\n                            mApp.getPackageName().toString(), mApp.getName().toString(),\n                            itemView, new Rect(0, 0, itemView.getMeasuredWidth(), itemView.getMeasuredHeight()));\n                }\n            });\n            mToggleAppVisibility.setOnClickListener(new View.OnClickListener() {\n                @Override\n                public void onClick(View v) {\n                    if (mApp != null) {\n                        sendChangeAppsVisibilityBroadcast();\n                        toggleAppVisibility(mApp);\n                    } else {\n                        Snackbar.make(mContainer, mContext.getString(R.string.error_app_not_found), Snackbar.LENGTH_LONG).show();\n                    }\n                }\n            });\n\n            mMenu.setOnClickListener(new View.OnClickListener() {\n                @Override\n                public void onClick(View view) {\n                    PopupMenu popupMenu = new PopupMenu(mContext, view);\n                    popupMenu.setOnMenuItemClickListener(AppViewHolder.this);\n                    popupMenu.inflate(R.menu.menu_app);\n                    popupMenu.show();\n                }\n            });\n        }\n\n        @Override\n        public boolean onMenuItemClick(MenuItem item) {\n            switch (item.getItemId()) {\n                case R.id.menu_item_element_app_info:\n                    try {\n                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);\n                        intent.setData(Uri.parse(\"package:\" + mApp.getPackageName()));\n                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\n                        mContext.startActivity(intent);\n                    } catch (ActivityNotFoundException e) {\n                        Toast.makeText(mContext, R.string.error_app_not_found, Toast.LENGTH_SHORT).show();\n                    }\n                    return true;\n                case R.id.menu_item_element_uninstall:\n                    try {\n                        Intent intent = new Intent(Intent.ACTION_DELETE);\n                        intent.setData(Uri.parse(\"package:\" + mApp.getPackageName()));\n                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\n                        mContext.startActivity(intent);\n                    } catch (ActivityNotFoundException e) {\n                        Toast.makeText(mContext, R.string.error_app_not_found, Toast.LENGTH_SHORT).show();\n                    }\n                    return true;\n            }\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/background/BackgroundChangedObservable.java",
    "content": "package nickrout.lenslauncher.background;\n\nimport java.util.Observable;\n\npublic class BackgroundChangedObservable extends Observable {\n    private static BackgroundChangedObservable instance = new BackgroundChangedObservable();\n\n    public static BackgroundChangedObservable getInstance() {\n        return instance;\n    }\n\n    private BackgroundChangedObservable() {\n    }\n\n    public void updateValue(Object data) {\n        synchronized (this) {\n            setChanged();\n            notifyObservers(data);\n        }\n    }\n\n    public void update() {\n        updateValue(null);\n    }\n}"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/background/BroadcastReceivers.java",
    "content": "package nickrout.lenslauncher.background;\n\nimport android.content.BroadcastReceiver;\nimport android.content.Context;\nimport android.content.Intent;\n\n/**\n * Created by nicholasrout on 2016/06/12.\n */\npublic class BroadcastReceivers {\n\n    public static class AppsUpdatedReceiver extends BroadcastReceiver {\n        @Override\n        public void onReceive(Context context, Intent intent) {\n            UpdatedObservable.getInstance().update();\n        }\n    }\n\n    public static class AppsEditedReceiver extends BroadcastReceiver {\n        @Override\n        public void onReceive(Context context, Intent intent) {\n            EditedObservable.getInstance().update();\n        }\n    }\n\n    public static class AppsVisibilityChangedReceiver extends BroadcastReceiver {\n        @Override\n        public void onReceive(Context context, Intent intent) {\n            VisibilityChangedObservable.getInstance().update();\n        }\n    }\n\n    public static class AppsLoadedReceiver extends BroadcastReceiver {\n        @Override\n        public void onReceive(Context context, Intent intent) {\n            LoadedObservable.getInstance().update();\n        }\n    }\n\n    public static class BackgroundChangedReceiver extends BroadcastReceiver {\n        @Override\n        public void onReceive(Context context, Intent intent) {\n            BackgroundChangedObservable.getInstance().update();\n        }\n    }\n\n    public static class NightModeReceiver extends BroadcastReceiver {\n        @Override\n        public void onReceive(Context context, Intent intent) {\n            NightModeObservable.getInstance().update();\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/background/EditedObservable.java",
    "content": "package nickrout.lenslauncher.background;\n\nimport java.util.Observable;\n\n/**\n * Created by nicholasrout on 2016/06/23.\n */\npublic class EditedObservable extends Observable {\n    private static EditedObservable instance = new EditedObservable();\n\n    public static EditedObservable getInstance() {\n        return instance;\n    }\n\n    private EditedObservable() {\n    }\n\n    public void updateValue(Object data) {\n        synchronized (this) {\n            setChanged();\n            notifyObservers(data);\n        }\n    }\n\n    public void update() {\n        updateValue(null);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/background/LoadedObservable.java",
    "content": "package nickrout.lenslauncher.background;\n\nimport java.util.Observable;\n\n/**\n * Created by nicholasrout on 2016/06/12.\n */\npublic class LoadedObservable extends Observable {\n    private static LoadedObservable instance = new LoadedObservable();\n\n    public static LoadedObservable getInstance() {\n        return instance;\n    }\n\n    private LoadedObservable() {\n    }\n\n    public void updateValue(Object data) {\n        synchronized (this) {\n            setChanged();\n            notifyObservers(data);\n        }\n    }\n\n    public void update() {\n        updateValue(null);\n    }\n}"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/background/NightModeObservable.java",
    "content": "package nickrout.lenslauncher.background;\n\nimport java.util.Observable;\n\n/**\n * Created by nicholasrout on 2017/01/15.\n */\n\npublic class NightModeObservable extends Observable {\n    private static NightModeObservable instance = new NightModeObservable();\n\n    public static NightModeObservable getInstance() {\n        return instance;\n    }\n\n    private NightModeObservable() {\n    }\n\n    public void updateValue(Object data) {\n        synchronized (this) {\n            setChanged();\n            notifyObservers(data);\n        }\n    }\n\n    public void update() {\n        updateValue(null);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/background/SortAppsTask.java",
    "content": "package nickrout.lenslauncher.background;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.os.AsyncTask;\n\nimport java.util.ArrayList;\n\nimport nickrout.lenslauncher.model.App;\nimport nickrout.lenslauncher.util.AppSorter;\nimport nickrout.lenslauncher.AppsSingleton;\nimport nickrout.lenslauncher.util.Settings;\n\n/**\n * Created by nicholasrout on 2016/06/23.\n */\npublic class SortAppsTask extends AsyncTask<Void, Void, Void> {\n\n    private Context mContext;\n    private Application mApplication;\n    private Settings mSettings;\n\n    private ArrayList<App> mApps;\n    private ArrayList<Bitmap> mAppIcons;\n\n    public SortAppsTask(Context context,\n                        Application application) {\n        mContext = context;\n        mApplication = application;\n        mSettings = new Settings(mContext);\n    }\n\n    @Override\n    protected void onPreExecute() {\n        super.onPreExecute();\n    }\n\n    @Override\n    protected Void doInBackground(Void... params) {\n        ArrayList<App> apps = AppsSingleton.getInstance().getApps();\n        AppSorter.sort(apps, mSettings.getSortType());\n        mApps = new ArrayList<>();\n        mAppIcons = new ArrayList<>();\n        for (int i = 0; i < apps.size(); i++) {\n            App app = apps.get(i);\n            Bitmap appIcon = app.getIcon();\n            if (appIcon != null) {\n                mApps.add(app);\n                mAppIcons.add(appIcon);\n            }\n        }\n        return null;\n    }\n\n    @Override\n    protected void onPostExecute(Void result) {\n        AppsSingleton.getInstance().setApps(mApps);\n        AppsSingleton.getInstance().setAppIcons(mAppIcons);\n        Intent appsLoadedIntent = new Intent(mApplication, BroadcastReceivers.AppsLoadedReceiver.class);\n        mApplication.sendBroadcast(appsLoadedIntent);\n        super.onPostExecute(result);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/background/UpdateAppsTask.java",
    "content": "package nickrout.lenslauncher.background;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.pm.PackageManager;\nimport android.graphics.Bitmap;\nimport android.os.AsyncTask;\n\nimport java.util.ArrayList;\n\nimport nickrout.lenslauncher.model.App;\nimport nickrout.lenslauncher.util.AppUtil;\nimport nickrout.lenslauncher.AppsSingleton;\nimport nickrout.lenslauncher.util.Settings;\n\n/**\n * Created by rish on 26/5/16.\n */\npublic class UpdateAppsTask extends AsyncTask<Void, Void, Void> {\n\n    private PackageManager mPackageManager;\n    private Context mContext;\n    private Application mApplication;\n    private Settings mSettings;\n\n    private ArrayList<App> mApps;\n    private ArrayList<Bitmap> mAppIcons;\n\n    public UpdateAppsTask(PackageManager packageManager,\n                           Context context,\n                           Application application) {\n        this.mPackageManager = packageManager;\n        this.mContext = context;\n        this.mApplication = application;\n        this.mSettings = new Settings(context);\n    }\n\n    @Override\n    protected void onPreExecute() {\n        super.onPreExecute();\n    }\n\n    @Override\n    protected Void doInBackground(Void... params) {\n        ArrayList<App> apps = AppUtil.getApps(\n                mPackageManager,\n                mContext,\n                mApplication,\n                mSettings.getString(Settings.KEY_ICON_PACK_LABEL_NAME),\n                mSettings.getSortType());\n        mApps = new ArrayList<>();\n        mAppIcons = new ArrayList<>();\n        for (int i = 0; i < apps.size(); i++) {\n            App app = apps.get(i);\n            Bitmap appIcon = app.getIcon();\n            if (appIcon != null) {\n                mApps.add(app);\n                mAppIcons.add(appIcon);\n            }\n        }\n        return null;\n    }\n\n    @Override\n    protected void onPostExecute(Void result) {\n        AppsSingleton.getInstance().setApps(mApps);\n        AppsSingleton.getInstance().setAppIcons(mAppIcons);\n        Intent appsLoadedIntent = new Intent(mApplication, BroadcastReceivers.AppsLoadedReceiver.class);\n        mApplication.sendBroadcast(appsLoadedIntent);\n        super.onPostExecute(result);\n    }\n}"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/background/UpdatedObservable.java",
    "content": "package nickrout.lenslauncher.background;\n\nimport java.util.Observable;\n\n/**\n * Created by nickrout on 2016/04/08.\n */\npublic class UpdatedObservable extends Observable {\n    private static UpdatedObservable instance = new UpdatedObservable();\n\n    public static UpdatedObservable getInstance() {\n        return instance;\n    }\n\n    private UpdatedObservable() {\n    }\n\n    public void updateValue(Object data) {\n        synchronized (this) {\n            setChanged();\n            notifyObservers(data);\n        }\n    }\n\n    public void update() {\n        updateValue(null);\n    }\n}"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/background/VisibilityChangedObservable.java",
    "content": "package nickrout.lenslauncher.background;\n\nimport java.util.Observable;\n\npublic class VisibilityChangedObservable extends Observable {\n    private static VisibilityChangedObservable instance = new VisibilityChangedObservable();\n\n    public static VisibilityChangedObservable getInstance() {\n        return instance;\n    }\n\n    private VisibilityChangedObservable() {\n    }\n\n    public void updateValue(Object data) {\n        synchronized (this) {\n            setChanged();\n            notifyObservers(data);\n        }\n    }\n\n    public void update() {\n        updateValue(null);\n    }\n}"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/model/App.java",
    "content": "package nickrout.lenslauncher.model;\n\nimport android.graphics.Bitmap;\nimport android.support.annotation.ColorInt;\n\n/**\n * Created by nickrout on 2016/04/02.\n */\npublic class App {\n\n    private int mId;\n    private CharSequence mLabel;\n    private CharSequence mPackageName;\n    private CharSequence mName;\n    private int mIconResId;\n    private Bitmap mIcon;\n    private long mInstallDate;\n    private @ColorInt int mPaletteColor;\n\n    public App() {\n    }\n\n    public int getId() {\n        return mId;\n    }\n\n    public void setId(int mId) {\n        this.mId = mId;\n    }\n\n    public CharSequence getLabel() {\n        return mLabel;\n    }\n\n    public void setLabel(CharSequence label) {\n        mLabel = label;\n    }\n\n    public CharSequence getPackageName() {\n        return mPackageName;\n    }\n\n    public void setPackageName(CharSequence packageName) {\n        mPackageName = packageName;\n    }\n\n    public CharSequence getName() {\n        return mName;\n    }\n\n    public void setName(CharSequence name) {\n        mName = name;\n    }\n\n    public int getIconResId() {\n        return mIconResId;\n    }\n\n    public void setIconResId(int iconResId) {\n        mIconResId = iconResId;\n    }\n\n    public Bitmap getIcon() {\n        return mIcon;\n    }\n\n    public void setIcon(Bitmap icon) {\n        mIcon = icon;\n    }\n\n    public long getInstallDate() {\n        return mInstallDate;\n    }\n\n    public void setInstallDate(long mInstallDate) {\n        this.mInstallDate = mInstallDate;\n    }\n\n    public int getPaletteColor() {\n        return mPaletteColor;\n    }\n\n    public void setPaletteColor(int paletteColor) {\n        mPaletteColor = paletteColor;\n    }\n\n    @Override\n    public String toString() {\n        return \"App{\" +\n                \"mId=\" + mId +\n                \", mLabel=\" + mLabel +\n                \", mPackageName=\" + mPackageName +\n                \", mName=\" + mName +\n                \", mIconResId=\" + mIconResId +\n                \", mIcon=\" + mIcon +\n                \", mInstallDate=\" + mInstallDate +\n                \", mPaletteColor=\" + mPaletteColor +\n                '}';\n    }\n}"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/model/AppPersistent.java",
    "content": "package nickrout.lenslauncher.model;\n\nimport com.orm.SugarRecord;\nimport com.orm.query.Condition;\nimport com.orm.query.Select;\nimport com.orm.util.NamingHelper;\n\n/**\n * Created by rish on 20/5/16.\n */\npublic class AppPersistent extends SugarRecord {\n\n    private static final String TAG = \"AppPersistent\";\n\n    /* Required Default Constructor */\n    public AppPersistent() {\n    }\n\n    private String mPackageName;\n    private String mName;\n    private String mIdentifier;\n    private long mOpenCount;\n    private int mOrderNumber;\n    private boolean mAppVisible;\n\n    private static boolean DEFAULT_APP_VISIBILITY = true;\n    private static int DEFAULT_ORDER_NUMBER = -1;\n    private static long DEFAULT_OPEN_COUNT = 1;\n\n    public AppPersistent(String packageName, String name, long openCount, int orderNumber, boolean appVisible) {\n        this.mPackageName = packageName;\n        this.mName = name;\n        this.mIdentifier = AppPersistent.generateIdentifier(packageName, name);\n        this.mOpenCount = openCount;\n        this.mOrderNumber = orderNumber;\n        this.mAppVisible = appVisible;\n    }\n\n    public String getPackageName() {\n        return mPackageName;\n    }\n\n    public void setPackageName(String packageName) {\n        this.mPackageName = packageName;\n        this.mIdentifier =\n                AppPersistent.generateIdentifier(this.mPackageName, this.mName);\n    }\n\n    public String getName() {\n        return mName;\n    }\n\n    public void setName(String name) {\n        mName = name;\n        this.mIdentifier =\n                AppPersistent.generateIdentifier(this.mPackageName, this.mName);\n    }\n\n    public String getIdentifier() {\n        return mIdentifier;\n    }\n\n    public long getOpenCount() {\n        return mOpenCount;\n    }\n\n    public void setOpenCount(long openCount) {\n        this.mOpenCount = openCount;\n    }\n\n    public int getOrderNumber() {\n        return mOrderNumber;\n    }\n\n    public void setOrderNumber(int orderNumber) {\n        this.mOrderNumber = orderNumber;\n    }\n\n    public boolean isAppVisible() {\n        return mAppVisible;\n    }\n\n    public void setAppVisible(boolean appVisible) {\n        this.mAppVisible = appVisible;\n    }\n\n    @Override\n    public String toString() {\n        return \"AppPersistent{\" +\n                \"mPackageName='\" + mPackageName + '\\'' +\n                \", mName='\" + mName + '\\'' +\n                \", mIdentifier='\" + mIdentifier + '\\'' +\n                \", mOpenCount=\" + mOpenCount +\n                \", mOrderNumber=\" + mOrderNumber +\n                \", mAppVisible=\" + mAppVisible +\n                '}';\n    }\n\n    public static String generateIdentifier(String packageName, String name) {\n        return packageName + \"-\" + name;\n    }\n\n    public static void incrementAppCount(String packageName, String name) {\n        String identifier = AppPersistent.generateIdentifier(packageName, name);\n        AppPersistent appPersistent = Select.from(AppPersistent.class).where(Condition.prop(NamingHelper.toSQLNameDefault(\"mIdentifier\")).eq(identifier)).first();\n        if (appPersistent != null) {\n            appPersistent.setOpenCount(appPersistent.getOpenCount() + 1);\n            appPersistent.save();\n        } else {\n            AppPersistent newAppPersistent = new AppPersistent(packageName, name, DEFAULT_OPEN_COUNT, DEFAULT_ORDER_NUMBER, DEFAULT_APP_VISIBILITY);\n            newAppPersistent.save();\n        }\n    }\n\n    public static void setAppOrderNumber(String packageName, String name, int orderNumber) {\n        String identifier = AppPersistent.generateIdentifier(packageName, name);\n        AppPersistent appPersistent = Select.from(AppPersistent.class).where(Condition.prop(NamingHelper.toSQLNameDefault(\"mIdentifier\")).eq(identifier)).first();\n        if (appPersistent != null) {\n            appPersistent.setOrderNumber(orderNumber);\n            appPersistent.save();\n        } else {\n            AppPersistent newAppPersistent = new AppPersistent(packageName, name, DEFAULT_OPEN_COUNT, DEFAULT_ORDER_NUMBER, DEFAULT_APP_VISIBILITY);\n            newAppPersistent.save();\n        }\n    }\n\n    public static boolean getAppVisibility(String packageName, String name) {\n        String identifier = AppPersistent.generateIdentifier(packageName, name);\n        AppPersistent appPersistent = Select.from(AppPersistent.class).where(Condition.prop(NamingHelper.toSQLNameDefault(\"mIdentifier\")).eq(identifier)).first();\n        if (appPersistent != null) {\n            return appPersistent.isAppVisible();\n        } else {\n            return true;\n        }\n    }\n\n    public static void setAppVisibility(String packageName, String name, boolean mHideApp) {\n        String identifier = AppPersistent.generateIdentifier(packageName, name);\n        AppPersistent appPersistent = Select.from(AppPersistent.class).where(Condition.prop(NamingHelper.toSQLNameDefault(\"mIdentifier\")).eq(identifier)).first();\n        if (appPersistent != null) {\n            appPersistent.setAppVisible(mHideApp);\n            appPersistent.save();\n        } else {\n            AppPersistent newAppPersistent = new AppPersistent(packageName, name, DEFAULT_OPEN_COUNT, DEFAULT_ORDER_NUMBER, mHideApp);\n            newAppPersistent.save();\n        }\n    }\n\n    public static long getAppOpenCount(String packageName, String name) {\n        String identifier = AppPersistent.generateIdentifier(packageName, name);\n        AppPersistent appPersistent = Select.from(AppPersistent.class).where(Condition.prop(NamingHelper.toSQLNameDefault(\"mIdentifier\")).eq(identifier)).first();\n        if (appPersistent != null) {\n            return appPersistent.getOpenCount();\n        } else {\n            return 0;\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/model/Grid.java",
    "content": "package nickrout.lenslauncher.model;\n\n/**\n * Created by nickrout on 2016/04/02.\n */\npublic class Grid {\n\n    private int mItemCount;\n    private int mItemCountHorizontal;\n    private int mItemCountVertical;\n    private float mItemSize;\n    private float mSpacingHorizontal;\n    private float mSpacingVertical;\n\n    public Grid() {}\n\n    public int getItemCount() {\n        return mItemCount;\n    }\n\n    public void setItemCount(int itemCount) {\n        mItemCount = itemCount;\n    }\n\n    public int getItemCountHorizontal() {\n        return mItemCountHorizontal;\n    }\n\n    public void setItemCountHorizontal(int itemCountHorizontal) {\n        mItemCountHorizontal = itemCountHorizontal;\n    }\n\n    public int getItemCountVertical() {\n        return mItemCountVertical;\n    }\n\n    public void setItemCountVertical(int itemCountVertical) {\n        mItemCountVertical = itemCountVertical;\n    }\n\n    public float getItemSize() {\n        return mItemSize;\n    }\n\n    public void setItemSize(float itemSize) {\n        mItemSize = itemSize;\n    }\n\n    public float getSpacingHorizontal() {\n        return mSpacingHorizontal;\n    }\n\n    public void setSpacingHorizontal(float spacingHorizontal) {\n        mSpacingHorizontal = spacingHorizontal;\n    }\n\n    public float getSpacingVertical() {\n        return mSpacingVertical;\n    }\n\n    public void setSpacingVertical(float spacingVertical) {\n        mSpacingVertical = spacingVertical;\n    }\n\n    @Override\n    public String toString() {\n        return \"Grid{\" +\n                \"mItemCount=\" + mItemCount +\n                \", mItemCountHorizontal=\" + mItemCountHorizontal +\n                \", mItemCountVertical=\" + mItemCountVertical +\n                \", mItemSize=\" + mItemSize +\n                \", mSpacingHorizontal=\" + mSpacingHorizontal +\n                \", mSpacingVertical=\" + mSpacingVertical +\n                '}';\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/ui/AboutActivity.java",
    "content": "package nickrout.lenslauncher.ui;\n\nimport android.animation.Animator;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.support.design.widget.CollapsingToolbarLayout;\nimport android.support.v4.content.ContextCompat;\nimport android.support.v7.widget.Toolbar;\nimport android.text.Html;\nimport android.text.method.LinkMovementMethod;\nimport android.view.MenuItem;\nimport android.view.View;\nimport android.view.ViewAnimationUtils;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport java.util.Observable;\nimport java.util.Observer;\n\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport nickrout.lenslauncher.R;\nimport nickrout.lenslauncher.background.NightModeObservable;\n\n/**\n * Created by nickrout on 2016/04/06.\n */\npublic class AboutActivity extends BaseActivity implements Observer {\n\n    private static final String TAG = \"AboutActivity\";\n\n    @BindView(R.id.text_view_about)\n    TextView mTextViewAbout;\n\n    @BindView(R.id.backdrop)\n    ImageView mImageAbout;\n\n    @BindView(R.id.collapsing_toolbar)\n    CollapsingToolbarLayout mCollapsingToolbar;\n\n    @BindView(R.id.toolbar)\n    Toolbar mToolbar;\n\n    @Override\n    protected void onCreate(@Nullable Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_about);\n        ButterKnife.bind(this);\n        setSupportActionBar(mToolbar);\n        getSupportActionBar().setDisplayHomeAsUpEnabled(true);\n        mCollapsingToolbar.setExpandedTitleColor(ContextCompat.getColor(this, R.color.colorTransparent));\n        setupViews();\n        mImageAbout.postDelayed(new Runnable() {\n            @Override\n            public void run() {\n                circularRevealAboutImage();\n            }\n        }, 150);\n        NightModeObservable.getInstance().addObserver(this);\n    }\n\n    private void circularRevealAboutImage() {\n        if (mImageAbout != null) {\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n                int cx = mImageAbout.getWidth() / 2;\n                int cy = mImageAbout.getHeight() / 2;\n                float finalRadius = (float) Math.hypot(cx, cy);\n                Animator anim =\n                        ViewAnimationUtils.createCircularReveal(mImageAbout, cx, cy, 0, finalRadius);\n                mImageAbout.setVisibility(View.VISIBLE);\n                anim.start();\n            } else {\n                mImageAbout.setVisibility(View.VISIBLE);\n            }\n        }\n    }\n\n    private void setupViews() {\n        mTextViewAbout.setText(Html.fromHtml(getString(R.string.about)));\n        mTextViewAbout.setMovementMethod(LinkMovementMethod.getInstance());\n    }\n\n    @Override\n    public void onBackPressed() {\n        finish();\n    }\n\n    @Override\n    public void finish() {\n        super.finish();\n        overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        switch (item.getItemId()) {\n            case android.R.id.home:\n                finish();\n                return true;\n        }\n        return super.onOptionsItemSelected(item);\n    }\n\n    @Override\n    public void update(Observable observable, Object o) {\n        if (observable instanceof NightModeObservable) {\n            updateNightMode();\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/ui/AppsFragment.java",
    "content": "package nickrout.lenslauncher.ui;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.support.v4.app.Fragment;\nimport android.support.v7.widget.DefaultItemAnimator;\nimport android.support.v7.widget.GridLayoutManager;\nimport android.support.v7.widget.LinearLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport java.util.ArrayList;\n\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport me.zhanghai.android.materialprogressbar.MaterialProgressBar;\nimport nickrout.lenslauncher.R;\nimport nickrout.lenslauncher.adapter.AppRecyclerAdapter;\nimport nickrout.lenslauncher.model.App;\nimport nickrout.lenslauncher.util.AppSorter;\nimport nickrout.lenslauncher.AppsSingleton;\nimport nickrout.lenslauncher.background.BroadcastReceivers;\nimport nickrout.lenslauncher.util.Settings;\n\n/**\n * Created by nicholasrout on 2016/06/08.\n */\npublic class AppsFragment extends Fragment implements SettingsActivity.AppsInterface {\n\n    private static final String TAG = \"AppsFragment\";\n\n    @BindView(R.id.recycler_apps)\n    RecyclerView mRecycler;\n\n    @BindView(R.id.progress_apps)\n    MaterialProgressBar mProgress;\n\n    private Settings mSettings;\n    private AppRecyclerAdapter mAppRecyclerAdapter;\n    private int mScrolledItemIndex;\n\n    public AppsFragment() {\n    }\n\n    public static AppsFragment newInstance() {\n        AppsFragment appsFragment = new AppsFragment();\n        // Include potential bundle extras here\n        return appsFragment;\n    }\n\n    @Nullable\n    @Override\n    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {\n        View view = inflater.inflate(R.layout.fragment_apps, container, false);\n        ButterKnife.bind(this, view);\n        mSettings = new Settings(getActivity());\n        setupRecycler(AppsSingleton.getInstance().getApps());\n        return view;\n    }\n\n    @Override\n    public void onAttach(Context context) {\n        super.onAttach(context);\n        if (getActivity() != null && getActivity() instanceof SettingsActivity) {\n            ((SettingsActivity) getActivity()).setAppsInterface(this);\n        }\n    }\n\n    private void sendEditAppsBroadcast() {\n        if (getActivity() == null) {\n            return;\n        }\n        Intent editAppsIntent = new Intent(getActivity(), BroadcastReceivers.AppsEditedReceiver.class);\n        getActivity().sendBroadcast(editAppsIntent);\n    }\n\n    private void setupRecycler(ArrayList<App> apps) {\n        if (getActivity() == null || apps.size() == 0) {\n            return;\n        }\n        if (mRecycler.getLayoutManager() != null) {\n            mScrolledItemIndex = ((LinearLayoutManager) mRecycler.getLayoutManager()).findFirstCompletelyVisibleItemPosition();\n        }\n        mProgress.setVisibility(View.INVISIBLE);\n        mRecycler.setVisibility(View.VISIBLE);\n        mAppRecyclerAdapter = new AppRecyclerAdapter(getActivity(), apps);\n        mRecycler.setAdapter(mAppRecyclerAdapter);\n        mRecycler.setLayoutManager(new GridLayoutManager(getActivity(), getResources().getInteger(R.integer.columns_apps)));\n        mRecycler.setItemAnimator(new DefaultItemAnimator());\n        mRecycler.scrollToPosition(mScrolledItemIndex);\n        mScrolledItemIndex = 0;\n    }\n\n    @Override\n    public void onDefaultsReset() {\n        if (mSettings.getSortType() != AppSorter.SortType.values()[Settings.DEFAULT_SORT_TYPE]) {\n            mSettings.save(Settings.KEY_SORT_TYPE, Settings.DEFAULT_SORT_TYPE);\n            sendEditAppsBroadcast();\n        }\n    }\n\n    @Override\n    public void onAppsUpdated(ArrayList<App> apps) {\n        setupRecycler(apps);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/ui/BaseActivity.java",
    "content": "package nickrout.lenslauncher.ui;\n\nimport android.app.ActivityManager;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.support.annotation.LayoutRes;\nimport android.support.annotation.Nullable;\nimport android.support.v4.content.ContextCompat;\nimport android.support.v7.app.AppCompatActivity;\n\nimport nickrout.lenslauncher.R;\nimport nickrout.lenslauncher.util.Settings;\n\n/**\n * Created by nickrout on 2016/04/05.\n */\npublic class BaseActivity extends AppCompatActivity {\n\n    protected Settings mSettings;\n\n    @Override\n    protected void onCreate(@Nullable Bundle savedInstanceState) {\n        mSettings = new Settings(this);\n        if (savedInstanceState == null) {\n            updateNightMode();\n        }\n        super.onCreate(savedInstanceState);\n    }\n\n    @Override\n    public void setContentView(@LayoutRes int layoutResID) {\n        super.setContentView(layoutResID);\n        setTaskDescription();\n    }\n\n    private void setTaskDescription() {\n        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n            Bitmap appIconBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);\n            ActivityManager.TaskDescription taskDescription = new ActivityManager.TaskDescription(\n                    getString(R.string.app_name),\n                    appIconBitmap,\n                    ContextCompat.getColor(getBaseContext(), R.color.colorPrimaryDark));\n            setTaskDescription(taskDescription);\n        }\n    }\n\n    protected void updateNightMode() {\n        if (mSettings == null) {\n            mSettings = new Settings(this);\n        }\n        getDelegate().setLocalNightMode(mSettings.getNightMode());\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/ui/FakeLauncherActivity.java",
    "content": "package nickrout.lenslauncher.ui;\n\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\n\nimport nickrout.lenslauncher.R;\n\npublic class FakeLauncherActivity extends AppCompatActivity {\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_fake_launcher);\n    }\n}"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/ui/HomeActivity.java",
    "content": "package nickrout.lenslauncher.ui;\n\nimport android.annotation.TargetApi;\nimport android.content.pm.PackageManager;\nimport android.graphics.Bitmap;\nimport android.graphics.Color;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.view.View;\nimport android.view.Window;\nimport android.view.WindowManager;\n\nimport java.util.ArrayList;\nimport java.util.Observable;\nimport java.util.Observer;\n\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport me.zhanghai.android.materialprogressbar.MaterialProgressBar;\nimport nickrout.lenslauncher.R;\nimport nickrout.lenslauncher.background.BackgroundChangedObservable;\nimport nickrout.lenslauncher.background.NightModeObservable;\nimport nickrout.lenslauncher.background.VisibilityChangedObservable;\nimport nickrout.lenslauncher.model.App;\nimport nickrout.lenslauncher.model.AppPersistent;\nimport nickrout.lenslauncher.AppsSingleton;\nimport nickrout.lenslauncher.background.LoadedObservable;\n\n/**\n * Created by nickrout on 2016/04/02.\n */\npublic class HomeActivity extends BaseActivity implements Observer {\n\n    private final static String TAG = \"HomeActivity\";\n\n    @BindView(R.id.lens_view_apps)\n    LensView mLensView;\n\n    @BindView(R.id.progress_home)\n    MaterialProgressBar mProgress;\n\n    private PackageManager mPackageManager;\n    private ArrayList<App> mApps;\n    private ArrayList<Bitmap> mAppIcons;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_home);\n        ButterKnife.bind(this);\n        mPackageManager = getPackageManager();\n        mLensView.setPackageManager(mPackageManager);\n        mLensView.setSystemUiVisibility(\n                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);\n        assignApps(AppsSingleton.getInstance().getApps(), AppsSingleton.getInstance().getAppIcons());\n        LoadedObservable.getInstance().addObserver(this);\n        VisibilityChangedObservable.getInstance().addObserver(this);\n        BackgroundChangedObservable.getInstance().addObserver(this);\n        NightModeObservable.getInstance().addObserver(this);\n    }\n\n    @Override\n    protected void onResume() {\n        super.onResume();\n        setupTransparentSystemBarsForLollipop();\n    }\n\n    /**\n     * Sets up transparent navigation and status bars in Lollipop.\n     * This method is a no-op for other platform versions.\n     */\n    @TargetApi(Build.VERSION_CODES.LOLLIPOP)\n    private void setupTransparentSystemBarsForLollipop() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n            Window window = getWindow();\n            window.getAttributes().systemUiVisibility |=\n                    (View.SYSTEM_UI_FLAG_LAYOUT_STABLE\n                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN\n                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);\n            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS\n                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);\n            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);\n            window.setStatusBarColor(Color.TRANSPARENT);\n            window.setNavigationBarColor(Color.TRANSPARENT);\n        }\n    }\n\n    private void setBackground() {\n        mLensView.invalidate();\n    }\n\n    private void assignApps(ArrayList<App> apps, ArrayList<Bitmap> appIcons) {\n        if (apps.size() == 0 || appIcons.size() == 0) {\n            return;\n        }\n        mProgress.setVisibility(View.INVISIBLE);\n        mLensView.setVisibility(View.VISIBLE);\n        mApps = apps;\n        mAppIcons = appIcons;\n        removeHiddenApps();\n        mLensView.setApps(mApps, mAppIcons);\n    }\n\n    private void removeHiddenApps() {\n        for (int i = 0; i < mApps.size(); i++) {\n            if (!AppPersistent.getAppVisibility(\n                    mApps.get(i).getPackageName().toString(), mApps.get(i).getName().toString())) {\n                mApps.remove(i);\n                mAppIcons.remove(i);\n                i--;\n            }\n        }\n    }\n\n    @Override\n    public void onBackPressed() {\n        // Do Nothing\n    }\n\n    @Override\n    protected void onDestroy() {\n        LoadedObservable.getInstance().deleteObserver(this);\n        super.onDestroy();\n    }\n\n    @Override\n    public void update(Observable observable, Object data) {\n        if (observable instanceof LoadedObservable || observable instanceof VisibilityChangedObservable) {\n            assignApps(AppsSingleton.getInstance().getApps(), AppsSingleton.getInstance().getAppIcons());\n        } else if (observable instanceof BackgroundChangedObservable) {\n            setBackground();\n        } else if (observable instanceof NightModeObservable) {\n            updateNightMode();\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/ui/LensFragment.java",
    "content": "package nickrout.lenslauncher.ui;\n\nimport android.content.Context;\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.support.v4.app.Fragment;\nimport android.support.v7.widget.AppCompatSeekBar;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.SeekBar;\nimport android.widget.TextView;\n\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport nickrout.lenslauncher.R;\nimport nickrout.lenslauncher.util.Settings;\n\n/**\n * Created by nicholasrout on 2016/06/08.\n */\npublic class LensFragment extends Fragment implements SettingsActivity.LensInterface {\n\n    private static final String TAG = \"LensFragment\";\n\n    @BindView(R.id.lens_view_settings)\n    LensView mLensView;\n\n    @BindView(R.id.seek_bar_min_icon_size)\n    AppCompatSeekBar mMinIconSize;\n\n    @BindView(R.id.value_min_icon_size)\n    TextView mValueMinIconSize;\n\n    @BindView(R.id.seek_bar_distortion_factor)\n    AppCompatSeekBar mDistortionFactor;\n\n    @BindView(R.id.value_distortion_factor)\n    TextView mValueDistortionFactor;\n\n    @BindView(R.id.seek_bar_scale_factor)\n    AppCompatSeekBar mScaleFactor;\n\n    @BindView(R.id.value_scale_factor)\n    TextView mValueScaleFactor;\n\n    @BindView(R.id.seek_bar_animation_time)\n    AppCompatSeekBar mAnimationTime;\n\n    @BindView(R.id.value_animation_time)\n    TextView mValueAnimationTime;\n\n    private Settings mSettings;\n\n    public LensFragment() {\n    }\n\n    public static LensFragment newInstance() {\n        LensFragment lensFragment = new LensFragment();\n        // Include potential bundle extras here\n        return lensFragment;\n    }\n\n    @Nullable\n    @Override\n    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {\n        View view = inflater.inflate(R.layout.fragment_lens, container, false);\n        ButterKnife.bind(this, view);\n        mSettings = new Settings(getActivity());\n        setupViews();\n        assignValues();\n        return view;\n    }\n\n    @Override\n    public void onAttach(Context context) {\n        super.onAttach(context);\n        if (getActivity() != null && getActivity() instanceof SettingsActivity) {\n            ((SettingsActivity) getActivity()).setLensInterface(this);\n        }\n    }\n\n    private void setupViews() {\n        mLensView.setDrawType(LensView.DrawType.CIRCLES);\n        mMinIconSize.setMax(Settings.MAX_ICON_SIZE);\n        mMinIconSize.setOnSeekBarChangeListener(new AppCompatSeekBar.OnSeekBarChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                int appropriateProgress = progress + (int) Settings.MIN_ICON_SIZE;\n                String minIconSize = appropriateProgress + \"dp\";\n                mValueMinIconSize.setText(minIconSize);\n                mSettings.save(Settings.KEY_ICON_SIZE, (float) appropriateProgress);\n                mLensView.invalidate();\n            }\n\n            @Override\n            public void onStartTrackingTouch(SeekBar seekBar) {\n            }\n\n            @Override\n            public void onStopTrackingTouch(SeekBar seekBar) {\n            }\n        });\n        mDistortionFactor.setMax(Settings.MAX_DISTORTION_FACTOR);\n        mDistortionFactor.setOnSeekBarChangeListener(new AppCompatSeekBar.OnSeekBarChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                float appropriateProgress = (float) progress / 2.0f + Settings.MIN_DISTORTION_FACTOR;\n                String distortionFactor = appropriateProgress + \"\";\n                mValueDistortionFactor.setText(distortionFactor);\n                mSettings.save(Settings.KEY_DISTORTION_FACTOR, appropriateProgress);\n                mLensView.invalidate();\n            }\n\n            @Override\n            public void onStartTrackingTouch(SeekBar seekBar) {\n            }\n\n            @Override\n            public void onStopTrackingTouch(SeekBar seekBar) {\n            }\n        });\n        mScaleFactor.setMax(Settings.MAX_SCALE_FACTOR);\n        mScaleFactor.setOnSeekBarChangeListener(new AppCompatSeekBar.OnSeekBarChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                float appropriateProgress = (float) progress / 5.0f + Settings.MIN_SCALE_FACTOR;\n                String scaleFactor = appropriateProgress + \"\";\n                mValueScaleFactor.setText(scaleFactor);\n                mSettings.save(Settings.KEY_SCALE_FACTOR, appropriateProgress);\n                mLensView.invalidate();\n            }\n\n            @Override\n            public void onStartTrackingTouch(SeekBar seekBar) {\n            }\n\n            @Override\n            public void onStopTrackingTouch(SeekBar seekBar) {\n            }\n        });\n        mAnimationTime.setMax(Settings.MAX_ANIMATION_TIME);\n        mAnimationTime.setOnSeekBarChangeListener(new AppCompatSeekBar.OnSeekBarChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                long appropriateProgress = (long) progress / 2 + Settings.MIN_ANIMATION_TIME;\n                String animationTime = appropriateProgress + \"ms\";\n                mValueAnimationTime.setText(animationTime);\n                mSettings.save(Settings.KEY_ANIMATION_TIME, appropriateProgress);\n            }\n\n            @Override\n            public void onStartTrackingTouch(SeekBar seekBar) {\n            }\n\n            @Override\n            public void onStopTrackingTouch(SeekBar seekBar) {\n            }\n        });\n    }\n\n    private void assignValues() {\n        mMinIconSize.setProgress((int) mSettings.getFloat(Settings.KEY_ICON_SIZE) - (int) Settings.MIN_ICON_SIZE);\n        String minIconSize = (int) mSettings.getFloat(Settings.KEY_ICON_SIZE) + \"dp\";\n        mValueMinIconSize.setText(minIconSize);\n        mDistortionFactor.setProgress((int) (2.0f * (mSettings.getFloat(Settings.KEY_DISTORTION_FACTOR) - Settings.MIN_DISTORTION_FACTOR)));\n        String distortionFactor = mSettings.getFloat(Settings.KEY_DISTORTION_FACTOR) + \"\";\n        mValueDistortionFactor.setText(distortionFactor);\n        mScaleFactor.setProgress((int) (5.0f * (mSettings.getFloat(Settings.KEY_SCALE_FACTOR) - Settings.MIN_SCALE_FACTOR)));\n        String scaleFactor = mSettings.getFloat(Settings.KEY_SCALE_FACTOR) + \"\";\n        mValueScaleFactor.setText(scaleFactor);\n        mAnimationTime.setProgress((int) (2 * (mSettings.getLong(Settings.KEY_ANIMATION_TIME) - Settings.MIN_ANIMATION_TIME)));\n        String animationTime = mSettings.getLong(Settings.KEY_ANIMATION_TIME) + \"ms\";\n        mValueAnimationTime.setText(animationTime);\n    }\n\n    @Override\n    public void onDefaultsReset() {\n        resetToDefault();\n        assignValues();\n    }\n\n    private void resetToDefault() {\n        mSettings.save(Settings.KEY_ICON_SIZE, Settings.DEFAULT_ICON_SIZE);\n        mSettings.save(Settings.KEY_DISTORTION_FACTOR, Settings.DEFAULT_DISTORTION_FACTOR);\n        mSettings.save(Settings.KEY_SCALE_FACTOR, Settings.DEFAULT_SCALE_FACTOR);\n        mSettings.save(Settings.KEY_ANIMATION_TIME, Settings.DEFAULT_ANIMATION_TIME);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/ui/LensView.java",
    "content": "package nickrout.lenslauncher.ui;\n\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport android.graphics.RectF;\nimport android.graphics.Typeface;\nimport android.graphics.drawable.NinePatchDrawable;\nimport android.os.Build;\nimport android.support.v4.content.ContextCompat;\nimport android.util.AttributeSet;\nimport android.view.HapticFeedbackConstants;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.view.ViewConfiguration;\nimport android.view.animation.AccelerateDecelerateInterpolator;\nimport android.view.animation.Animation;\nimport android.view.animation.Transformation;\n\nimport java.util.ArrayList;\n\nimport nickrout.lenslauncher.R;\nimport nickrout.lenslauncher.model.App;\nimport nickrout.lenslauncher.model.AppPersistent;\nimport nickrout.lenslauncher.model.Grid;\nimport nickrout.lenslauncher.util.AppUtil;\nimport nickrout.lenslauncher.util.LensCalculator;\nimport nickrout.lenslauncher.util.Settings;\n\n/**\n * Created by nickrout on 2016/04/02.\n */\npublic class LensView extends View {\n\n    private static final String TAG = \"LensView\";\n\n    private Paint mPaintIcons;\n    private Paint mPaintCircles;\n    private Paint mPaintTouchSelection;\n    private Paint mPaintText;\n    private Paint mPaintNewAppTag;\n\n    private float mTouchX = -Float.MAX_VALUE;\n    private float mTouchY = -Float.MAX_VALUE;\n\n    private boolean mInsideRect = false;\n    private RectF mRectToSelect = new RectF(0, 0, 0, 0);\n    private boolean mMustVibrate = true;\n    private int mSelectIndex;\n\n    private ArrayList<App> mApps;\n    private ArrayList<Bitmap> mAppIcons;\n    private PackageManager mPackageManager;\n\n    private float mAnimationMultiplier = 0.0f;\n    private boolean mAnimationHiding = false;\n\n    private int mNumberOfCircles;\n    private float mTouchSlop;\n    private boolean mMoving;\n\n    private Settings mSettings;\n\n    private NinePatchDrawable mWorkspaceBackgroundDrawable;\n\n    private Rect mInsets = new Rect(0, 0, 0, 0);\n\n    public enum DrawType {\n        APPS,\n        CIRCLES\n    }\n\n    private DrawType mDrawType;\n\n    public void setDrawType(DrawType drawType) {\n        mDrawType = drawType;\n        invalidate();\n    }\n\n    public LensView(Context context) {\n        super(context);\n        init();\n    }\n\n    public LensView(Context context, AttributeSet attrs) {\n        super(context, attrs);\n        init();\n    }\n\n    public LensView(Context context, AttributeSet attrs, int defStyle) {\n        super(context, attrs, defStyle);\n        init();\n    }\n\n    public void setApps(ArrayList<App> apps, ArrayList<Bitmap> appIcons) {\n        mApps = apps;\n        mAppIcons = appIcons;\n        invalidate();\n    }\n\n    public void setPackageManager(PackageManager packageManager) {\n        mPackageManager = packageManager;\n    }\n\n    private void init() {\n        mApps = new ArrayList<>();\n        mAppIcons = new ArrayList<>();\n        mDrawType = DrawType.APPS;\n        setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorTransparent));\n        mSettings = new Settings(getContext());\n        setupPaints();\n        mWorkspaceBackgroundDrawable = (NinePatchDrawable) ContextCompat.getDrawable(getContext(), R.drawable.workspace_bg);\n        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();\n    }\n\n    @Override\n    protected boolean fitSystemWindows(Rect insets) {\n        mInsets = insets;\n        return true;\n    }\n\n    private void setupPaints() {\n        mPaintIcons = new Paint();\n        mPaintIcons.setAntiAlias(true);\n        mPaintIcons.setStyle(Paint.Style.FILL);\n        mPaintIcons.setFilterBitmap(true);\n        mPaintIcons.setDither(true);\n\n        mPaintCircles = new Paint();\n        mPaintCircles.setAntiAlias(true);\n        mPaintCircles.setStyle(Paint.Style.FILL);\n        mPaintCircles.setColor(ContextCompat.getColor(getContext(), R.color.colorCircles));\n\n        mPaintTouchSelection = new Paint();\n        mPaintTouchSelection.setAntiAlias(true);\n        mPaintTouchSelection.setStyle(Paint.Style.STROKE);\n        mPaintTouchSelection.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));\n        mPaintTouchSelection.setStrokeWidth(getResources().getDimension(R.dimen.stroke_width_touch_selection));\n\n        mPaintText = new Paint();\n        mPaintText.setAntiAlias(true);\n        mPaintText.setStyle(Paint.Style.FILL);\n        mPaintText.setColor(ContextCompat.getColor(getContext(), R.color.colorWhite));\n        mPaintText.setTextSize(getResources().getDimension(R.dimen.text_size_lens));\n        mPaintText.setTextAlign(Paint.Align.CENTER);\n        mPaintText.setTypeface(Typeface.createFromAsset(getContext().getAssets(),\"fonts/RobotoCondensed-Regular.ttf\"));\n\n        mPaintNewAppTag = new Paint();\n        mPaintNewAppTag.setAntiAlias(true);\n        mPaintNewAppTag.setStyle(Paint.Style.FILL);\n        mPaintNewAppTag.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));\n        mPaintNewAppTag.setDither(true);\n        mPaintNewAppTag.setShadowLayer(getResources().getDimension(R.dimen.shadow_text),\n                getResources().getDimension(R.dimen.shadow_text),\n                getResources().getDimension(R.dimen.shadow_text),\n                ContextCompat.getColor(getContext(), R.color.colorShadow));\n    }\n\n    @Override\n    protected void onDraw(Canvas canvas) {\n        super.onDraw(canvas);\n        if (mDrawType == DrawType.APPS) {\n            if (mSettings.getString(Settings.KEY_BACKGROUND).equals(\"Color\")) {\n                canvas.drawColor(Color.parseColor(mSettings.getString(Settings.KEY_BACKGROUND_COLOR)));\n            }\n            mPaintNewAppTag.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));\n            drawWorkspaceBackground(canvas);\n            if (mApps != null) {\n                drawGrid(canvas, mApps.size());\n            }\n            if (mSettings.getBoolean(Settings.KEY_SHOW_TOUCH_SELECTION)) {\n                drawTouchSelection(canvas);\n            }\n        } else if (mDrawType == DrawType.CIRCLES) {\n            mNumberOfCircles = 100;\n            mTouchX = getWidth() / 2;\n            mTouchY = getHeight() / 2;\n            drawGrid(canvas, mNumberOfCircles);\n        }\n    }\n\n    @Override\n    public boolean onTouchEvent(MotionEvent event) {\n        if (mDrawType == DrawType.APPS) {\n            switch (event.getActionMasked()) {\n                case MotionEvent.ACTION_DOWN: {\n                    if (event.getX() < 0.0f) {\n                        mTouchX = 0.0f;\n                    } else {\n                        mTouchX = event.getX();\n                    }\n                    if (event.getY() < 0.0f) {\n                        mTouchY = 0.0f;\n                    } else {\n                        mTouchY = event.getY();\n                    }\n                    mSelectIndex = -1;\n                    mMoving = false;\n                    invalidate();\n                    return true;\n                }\n                case MotionEvent.ACTION_MOVE: {\n                    if (!mMoving && Math.sqrt(Math.pow(event.getX() - mTouchX, 2) + Math.pow(event.getY() - mTouchY, 2)) > mTouchSlop) {\n                        mMoving = true;\n                        LensAnimation lensShowAnimation = new LensAnimation(true);\n                        startAnimation(lensShowAnimation);\n                    }\n\n                    if (!mMoving) {\n                        return true;\n                    }\n\n                    if (event.getX() < 0.0f) {\n                        mTouchX = 0.0f;\n                    } else {\n                        mTouchX = event.getX();\n                    }\n                    if (event.getY() < 0.0f) {\n                        mTouchY = 0.0f;\n                    } else {\n                        mTouchY = event.getY();\n                    }\n                    invalidate();\n                    return true;\n                }\n                case MotionEvent.ACTION_UP: {\n                    performLaunchVibration();\n                    if (mMoving) {\n                        LensAnimation lensHideAnimation = new LensAnimation(false);\n                        startAnimation(lensHideAnimation);\n                        mMoving = false;\n                    } else {\n                        launchApp();\n                    }\n                    return true;\n                }\n                default: {\n                    return super.onTouchEvent(event);\n                }\n            }\n        }\n        return super.onTouchEvent(event);\n    }\n\n    private void drawWorkspaceBackground(Canvas canvas) {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n            Rect rect = new Rect(0, 0, getWidth(), getHeight());\n            mWorkspaceBackgroundDrawable.setBounds(rect);\n            mWorkspaceBackgroundDrawable.draw(canvas);\n        }\n    }\n\n    private void drawTouchSelection(Canvas canvas) {\n        canvas.drawCircle(mTouchX, mTouchY, getResources().getDimension(R.dimen.radius_touch_selection), mPaintTouchSelection);\n    }\n\n    private void drawGrid(Canvas canvas, int itemCount) {\n        Grid grid = LensCalculator.calculateGrid(\n                getContext(),\n                getWidth() - (mInsets.left + mInsets.right),\n                getHeight() - (mInsets.top + mInsets.bottom),\n                itemCount);\n        mInsideRect = false;\n        int selectIndex = -1;\n        mRectToSelect = null;\n\n        for (float y = 0.0f; y < (float) grid.getItemCountVertical(); y += 1.0f) {\n            for (float x = 0.0f; x < (float) grid.getItemCountHorizontal(); x += 1.0f) {\n\n                int currentItem = (int) (y * ((float) grid.getItemCountHorizontal()) + (x + 1.0f));\n                int currentIndex = currentItem - 1;\n\n                if (currentItem <= grid.getItemCount() || mDrawType == DrawType.CIRCLES) {\n                    RectF rect = new RectF();\n                    rect.left = mInsets.left + (x + 1.0f) * grid.getSpacingHorizontal() + x * grid.getItemSize();\n                    rect.top = mInsets.top + (y + 1.0f) * grid.getSpacingVertical() + y * grid.getItemSize();\n                    rect.right = rect.left + grid.getItemSize();\n                    rect.bottom = rect.top + grid.getItemSize();\n\n                    float animationMultiplier;\n                    if (mDrawType == DrawType.APPS) {\n                        animationMultiplier = mAnimationMultiplier;\n                    } else {\n                        animationMultiplier = 1.0f;\n                    }\n\n                    if (mTouchX >= 0 && mTouchY >= 0) {\n                        float shiftedCenterX = LensCalculator.shiftPoint(getContext(), mTouchX, rect.centerX(), getWidth(), animationMultiplier);\n                        float shiftedCenterY = LensCalculator.shiftPoint(getContext(), mTouchY, rect.centerY(), getHeight(), animationMultiplier);\n                        float scaledCenterX = LensCalculator.scalePoint(getContext(), mTouchX, rect.centerX(), rect.width(), getWidth(), animationMultiplier);\n                        float scaledCenterY = LensCalculator.scalePoint(getContext(), mTouchY, rect.centerY(), rect.height(), getHeight(), animationMultiplier);\n                        float newSize = LensCalculator.calculateSquareScaledSize(scaledCenterX, shiftedCenterX, scaledCenterY, shiftedCenterY);\n\n                        if (mSettings.getFloat(Settings.KEY_DISTORTION_FACTOR) > 0.0f && mSettings.getFloat(Settings.KEY_SCALE_FACTOR) > 0.0f) {\n                            rect = LensCalculator.calculateRect(shiftedCenterX, shiftedCenterY, newSize);\n                        } else if (mSettings.getFloat(Settings.KEY_DISTORTION_FACTOR) > 0.0f && mSettings.getFloat(Settings.KEY_SCALE_FACTOR) == 0.0f) {\n                            rect = LensCalculator.calculateRect(shiftedCenterX, shiftedCenterY, rect.width());\n                        }\n\n                        if (LensCalculator.isInsideRect(mTouchX, mTouchY, rect)) {\n                            mInsideRect = true;\n                            selectIndex = currentIndex;\n                            mRectToSelect = rect;\n                        }\n                    }\n\n                    if (mDrawType == DrawType.APPS) {\n                        drawAppIcon(canvas, rect, currentIndex);\n                    } else if (mDrawType == DrawType.CIRCLES) {\n                        drawCircle(canvas, rect);\n                    }\n                }\n            }\n        }\n\n        if (selectIndex >= 0) {\n            if (selectIndex != mSelectIndex) {\n                mMustVibrate = true;\n            } else {\n                mMustVibrate = false;\n            }\n        } else {\n            mMustVibrate = false;\n        }\n\n        if (!mAnimationHiding) {\n            mSelectIndex = selectIndex;\n        }\n\n        if (mDrawType == DrawType.APPS) {\n            performHoverVibration();\n        }\n\n        if (mRectToSelect != null && mDrawType == DrawType.APPS && mApps != null && mSelectIndex >= 0) {\n            drawAppName(canvas, mRectToSelect);\n        }\n    }\n\n    private void drawAppIcon(Canvas canvas, RectF rect, int index) {\n        if (index < mAppIcons.size()) {\n            Bitmap appIcon = mAppIcons.get(index);\n            Rect src = new Rect(0, 0, appIcon.getWidth(), appIcon.getHeight());\n            canvas.drawBitmap(appIcon, src, rect, mPaintIcons);\n\n            /**\n             * Check if the app was installed Settings.SHOW_NEW_APP_TAG_DURATION ago, and if it has been opened since.\n             * If not, drawNewAppTag()\n             */\n            if ((mApps.get(index).getInstallDate() >= (System.currentTimeMillis() - Settings.SHOW_NEW_APP_TAG_DURATION)\n                    && (AppPersistent.getAppOpenCount(\n                    mApps.get(index).getPackageName().toString(), mApps.get(index).getName().toString()) == 0))) {\n                drawNewAppTag(canvas, rect);\n            }\n        }\n    }\n\n    private void drawCircle(Canvas canvas, RectF rect) {\n        canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 2.0f, mPaintCircles);\n    }\n\n    private void drawAppName(Canvas canvas, RectF rect) {\n        if (mSettings.getBoolean(Settings.KEY_SHOW_NAME_APP_HOVER) && mMoving) {\n            canvas.drawText((String) mApps.get(mSelectIndex).getLabel(),\n                    rect.centerX(),\n                    rect.top - getResources().getDimension(R.dimen.margin_lens_text),\n                    mPaintText);\n        }\n    }\n\n    private void drawNewAppTag(Canvas canvas, RectF rect) {\n        if (mSettings.getBoolean(Settings.KEY_SHOW_NEW_APP_TAG)) {\n            canvas.drawCircle(rect.centerX(),\n                    rect.bottom + getResources().getDimension(R.dimen.margin_new_app_tag),\n                    getResources().getDimension(R.dimen.radius_new_app_tag),\n                    mPaintNewAppTag);\n        }\n    }\n\n    private void performHoverVibration() {\n        if (mInsideRect) {\n            if (mMustVibrate) {\n                if (mSettings.getBoolean(Settings.KEY_VIBRATE_APP_HOVER) && !mAnimationHiding) {\n                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);\n                }\n                mMustVibrate = false;\n            }\n        } else {\n            mMustVibrate = true;\n        }\n    }\n\n    private void performLaunchVibration() {\n        if (mInsideRect) {\n            if (mSettings.getBoolean(Settings.KEY_VIBRATE_APP_LAUNCH)) {\n                performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);\n            }\n        }\n    }\n\n    private void launchApp() {\n        if (mPackageManager != null && mApps != null && mSelectIndex >= 0) {\n            AppUtil.launchComponent(\n                    getContext(),\n                    (String) mApps.get(mSelectIndex).getPackageName(),\n                    (String) mApps.get(mSelectIndex).getName(),\n                    this,\n                    mRectToSelect == null ? null :\n                            new Rect((int) mRectToSelect.left, (int) mRectToSelect.top,\n                                    (int) mRectToSelect.right, (int) mRectToSelect.bottom));\n        }\n    }\n\n    private class LensAnimation extends Animation {\n\n        private boolean mShow;\n\n        public LensAnimation(boolean show) {\n            mShow = show;\n            setInterpolator(new AccelerateDecelerateInterpolator());\n            setDuration(mSettings.getLong(Settings.KEY_ANIMATION_TIME));\n            setAnimationListener(new AnimationListener() {\n                @Override\n                public void onAnimationStart(Animation animation) {\n                    if (!mShow) {\n                        mAnimationHiding = true;\n                        mPaintText.clearShadowLayer();\n                    } else {\n                        mAnimationHiding = false;\n                    }\n                }\n\n                @Override\n                public void onAnimationEnd(Animation animation) {\n                    if (!mShow) {\n                        launchApp();\n                        mTouchX = -Float.MAX_VALUE;\n                        mTouchY = -Float.MAX_VALUE;\n                        mAnimationHiding = false;\n                    } else {\n                        mPaintText.setShadowLayer(\n                                getResources().getDimension(R.dimen.shadow_text),\n                                getResources().getDimension(R.dimen.shadow_text),\n                                getResources().getDimension(R.dimen.shadow_text),\n                                ContextCompat.getColor(getContext(), R.color.colorShadow));\n                    }\n                }\n\n                @Override\n                public void onAnimationRepeat(Animation animation) {\n                }\n            });\n        }\n\n        @Override\n        protected void applyTransformation(float interpolatedTime, Transformation t) {\n            super.applyTransformation(interpolatedTime, t);\n            if (mShow) {\n                mAnimationMultiplier = interpolatedTime;\n                mPaintTouchSelection.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));\n                mPaintTouchSelection.setAlpha((int) (255.0f * interpolatedTime));\n                mPaintText.setAlpha((int) (255.0f * interpolatedTime));\n            } else {\n                mAnimationMultiplier = 1.0f - interpolatedTime;\n                mPaintTouchSelection.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));\n                mPaintTouchSelection.setAlpha((int) (255.0f * (1.0f - interpolatedTime)));\n                mPaintText.setAlpha((int) (255.0f * (1.0f - interpolatedTime)));\n            }\n            postInvalidate();\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/ui/SettingsActivity.java",
    "content": "package nickrout.lenslauncher.ui;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport android.support.annotation.ColorInt;\nimport android.support.annotation.NonNull;\nimport android.support.annotation.Nullable;\nimport android.support.design.widget.FloatingActionButton;\nimport android.support.design.widget.Snackbar;\nimport android.support.design.widget.TabLayout;\nimport android.support.v4.app.Fragment;\nimport android.support.v4.app.FragmentManager;\nimport android.support.v4.app.FragmentStatePagerAdapter;\nimport android.support.v4.view.ViewPager;\nimport android.support.v7.widget.Toolbar;\nimport android.view.Menu;\nimport android.view.MenuInflater;\nimport android.view.MenuItem;\nimport android.view.View;\n\nimport com.afollestad.materialdialogs.MaterialDialog;\nimport com.afollestad.materialdialogs.color.ColorChooserDialog;\n\nimport java.util.ArrayList;\nimport java.util.EnumSet;\nimport java.util.List;\nimport java.util.Observable;\nimport java.util.Observer;\n\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport butterknife.OnClick;\nimport nickrout.lenslauncher.R;\nimport nickrout.lenslauncher.background.NightModeObservable;\nimport nickrout.lenslauncher.model.App;\nimport nickrout.lenslauncher.util.AppSorter;\nimport nickrout.lenslauncher.AppsSingleton;\nimport nickrout.lenslauncher.background.BroadcastReceivers;\nimport nickrout.lenslauncher.util.IconPackManager;\nimport nickrout.lenslauncher.util.LauncherUtil;\nimport nickrout.lenslauncher.background.LoadedObservable;\nimport nickrout.lenslauncher.util.NightModeUtil;\nimport nickrout.lenslauncher.util.Settings;\n\n/**\n * Created by nicholasrout on 2016/06/07.\n */\npublic class SettingsActivity extends BaseActivity\n        implements Observer, ColorChooserDialog.ColorCallback {\n\n    private static final String TAG = \"SettingsActivity\";\n\n    private static final String COLOR_TAG_BACKGROUND = \"BackgroundColor\";\n    private static final String COLOR_TAG_HIGHLIGHT = \"HighlightColor\";\n\n\n    @BindView(R.id.toolbar)\n    Toolbar mToolbar;\n\n    @BindView(R.id.tabs)\n    TabLayout mTabLayout;\n\n    @BindView(R.id.viewpager)\n    ViewPager mViewPager;\n\n    @BindView(R.id.fab_sort)\n    FloatingActionButton mSortFab;\n\n    @OnClick(R.id.fab_sort)\n    public void onSortClicked() {\n        showSortTypeDialog();\n    }\n\n    private FragmentPagerAdapter mPagerAdapter;\n\n    private ArrayList<App> mApps;\n    private MaterialDialog mSortTypeDialog;\n    private MaterialDialog mIconPackDialog;\n    private MaterialDialog mNightModeDialog;\n    private MaterialDialog mBackgroundDialog;\n    private ColorChooserDialog mBackgroundColorDialog;\n    private ColorChooserDialog mHighlightColorDialog;\n\n    public interface LensInterface {\n        void onDefaultsReset();\n    }\n    private LensInterface mLensInterface;\n    public void setLensInterface(LensInterface lensInterface) {\n        mLensInterface = lensInterface;\n    }\n\n    public interface AppsInterface {\n        void onDefaultsReset();\n        void onAppsUpdated(ArrayList<App> apps);\n    }\n    private AppsInterface mAppsInterface;\n    public void setAppsInterface(AppsInterface appsInterface) {\n        mAppsInterface = appsInterface;\n    }\n\n    public interface SettingsInterface {\n        void onDefaultsReset();\n        void onValuesUpdated();\n    }\n    private SettingsInterface mSettingsInterface;\n    public void setSettingsInterface(SettingsInterface settingsInterface) {\n        mSettingsInterface = settingsInterface;\n    }\n\n    @Override\n    protected void onCreate(@Nullable Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_settings);\n        ButterKnife.bind(this);\n        mSortFab.hide();\n        setSupportActionBar(mToolbar);\n        mPagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager(), SettingsActivity.this);\n        mViewPager.setAdapter(mPagerAdapter);\n        mTabLayout.setupWithViewPager(mViewPager);\n        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {\n            @Override\n            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {\n            }\n\n            @Override\n            public void onPageSelected(int position) {\n                switch (position) {\n                    case 1:\n                        mSortFab.show();\n                        break;\n                    default:\n                        mSortFab.hide();\n                        break;\n                }\n            }\n\n            @Override\n            public void onPageScrollStateChanged(int state) {\n            }\n        });\n        mApps = AppsSingleton.getInstance().getApps();\n        LoadedObservable.getInstance().addObserver(this);\n        NightModeObservable.getInstance().addObserver(this);\n    }\n\n    @Override\n    public boolean onCreateOptionsMenu(Menu menu) {\n        MenuInflater inflater = getMenuInflater();\n        inflater.inflate(R.menu.menu_settings, menu);\n        return true;\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        switch (item.getItemId()) {\n            case R.id.menu_item_show_apps:\n                if (LauncherUtil.isLauncherDefault(getApplication())) {\n                    Intent homeIntent = new Intent(Intent.ACTION_MAIN);\n                    homeIntent.addCategory(Intent.CATEGORY_HOME);\n                    startActivity(homeIntent);\n                } else {\n                    Intent homeIntent = new Intent(SettingsActivity.this, HomeActivity.class);\n                    startActivity(homeIntent);\n                }\n                overridePendingTransition(R.anim.fade_in, R.anim.fade_out);\n                return true;\n            case R.id.menu_item_about:\n                Intent aboutIntent = new Intent(SettingsActivity.this, AboutActivity.class);\n                startActivity(aboutIntent);\n                overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);\n                return true;\n            case R.id.menu_item_reset_default_settings:\n                switch (mViewPager.getCurrentItem()) {\n                    case 0:\n                        if (mLensInterface != null) {\n                            mLensInterface.onDefaultsReset();\n                        }\n                        break;\n                    case 1:\n                        if (mAppsInterface != null) {\n                            mAppsInterface.onDefaultsReset();\n                        }\n                        break;\n                    case 2:\n                        if (mSettingsInterface != null) {\n                            mSettingsInterface.onDefaultsReset();\n                        }\n                        break;\n                }\n                Snackbar.make(mToolbar, getString(R.string.snackbar_reset_successful), Snackbar.LENGTH_LONG).show();\n                return true;\n            default:\n                return super.onOptionsItemSelected(item);\n        }\n    }\n\n    @Override\n    public void update(Observable observable, Object data) {\n        if (observable instanceof LoadedObservable) {\n            mApps = AppsSingleton.getInstance().getApps();\n            if (mAppsInterface != null) {\n                mAppsInterface.onAppsUpdated(mApps);\n            }\n        } else if (observable instanceof NightModeObservable) {\n            updateNightMode();\n        }\n    }\n\n    private void sendUpdateAppsBroadcast() {\n        Intent refreshAppsIntent = new Intent(SettingsActivity.this, BroadcastReceivers.AppsUpdatedReceiver.class);\n        sendBroadcast(refreshAppsIntent);\n    }\n\n    private void sendEditAppsBroadcast() {\n        Intent editAppsIntent = new Intent(SettingsActivity.this, BroadcastReceivers.AppsEditedReceiver.class);\n        sendBroadcast(editAppsIntent);\n    }\n\n    private void sendBackgroundChangedBroadcast() {\n        Intent changeBackgroundIntent = new Intent(SettingsActivity.this, BroadcastReceivers.BackgroundChangedReceiver.class);\n        sendBroadcast(changeBackgroundIntent);\n    }\n\n    public void sendNightModeBroadcast() {\n        Intent nightModeIntent = new Intent(SettingsActivity.this, BroadcastReceivers.NightModeReceiver.class);\n        sendBroadcast(nightModeIntent);\n    }\n\n    private void showSortTypeDialog() {\n        final List<AppSorter.SortType> sortTypes = new ArrayList<>(EnumSet.allOf(AppSorter.SortType.class));\n        final List<String> sortTypeStrings = new ArrayList<>();\n        for (int i = 0; i < sortTypes.size(); i++) {\n            sortTypeStrings.add(getApplicationContext().getString(sortTypes.get(i).getDisplayNameResId()));\n        }\n        AppSorter.SortType selectedSortType = mSettings.getSortType();\n        int selectedIndex = sortTypes.indexOf(selectedSortType);\n        mSortTypeDialog = new MaterialDialog.Builder(SettingsActivity.this)\n                .title(R.string.setting_sort_apps)\n                .items(sortTypeStrings)\n                .alwaysCallSingleChoiceCallback()\n                .itemsCallbackSingleChoice(selectedIndex, new MaterialDialog.ListCallbackSingleChoice() {\n                    @Override\n                    public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {\n                        mSettings.save(sortTypes.get(which));\n                        sendEditAppsBroadcast();\n                        return true;\n                    }\n                })\n                .show();\n    }\n\n    public void showIconPackDialog() {\n        final ArrayList<IconPackManager.IconPack> availableIconPacks =\n                new IconPackManager().getAvailableIconPacksWithIcons(true, getApplication());\n        final ArrayList<String> iconPackNames = new ArrayList<>();\n        iconPackNames.add(getString(R.string.setting_default_icon_pack));\n        for (int i = 0; i < availableIconPacks.size(); i++) {\n            if (iconPackNames.size() > 0 && !iconPackNames.contains(availableIconPacks.get(i).mName)) {\n                iconPackNames.add(availableIconPacks.get(i).mName);\n            }\n        }\n        String selectedPackageName = mSettings.getString(Settings.KEY_ICON_PACK_LABEL_NAME);\n        int selectedIndex = iconPackNames.indexOf(selectedPackageName);\n        mIconPackDialog = new MaterialDialog.Builder(SettingsActivity.this)\n                .title(R.string.setting_icon_pack)\n                .items(iconPackNames)\n                .alwaysCallSingleChoiceCallback()\n                .itemsCallbackSingleChoice(selectedIndex, new MaterialDialog.ListCallbackSingleChoice() {\n                    @Override\n                    public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {\n                        mSettings.save(Settings.KEY_ICON_PACK_LABEL_NAME, iconPackNames.get(which));\n                        if (mSettingsInterface != null) {\n                            mSettingsInterface.onValuesUpdated();\n                        }\n                        sendUpdateAppsBroadcast();\n                        return true;\n                    }\n                })\n                .show();\n    }\n\n    public void showHomeLauncherChooser() {\n        LauncherUtil.resetPreferredLauncherAndOpenChooser(getApplicationContext());\n    }\n\n    public void showNightModeChooser() {\n        String[] availableNightModes = getResources().getStringArray(R.array.night_modes);\n        final ArrayList<String> nightModes = new ArrayList<>();\n        for (int i = 0; i < availableNightModes.length; i++) {\n            nightModes.add(availableNightModes[i]);\n        }\n        String selectedNightMode = NightModeUtil.getNightModeDisplayName(mSettings.getNightMode());\n        int selectedIndex = nightModes.indexOf(selectedNightMode);\n        mNightModeDialog = new MaterialDialog.Builder(SettingsActivity.this)\n                .title(R.string.setting_night_mode)\n                .items(R.array.night_modes)\n                .alwaysCallSingleChoiceCallback()\n                .itemsCallbackSingleChoice(selectedIndex, new MaterialDialog.ListCallbackSingleChoice() {\n                    @Override\n                    public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {\n                        String selection = nightModes.get(which);\n                        mSettings.save(Settings.KEY_NIGHT_MODE, NightModeUtil.getNightModeFromDisplayName(selection));\n                        sendNightModeBroadcast();\n                        if (mSettingsInterface != null) {\n                            mSettingsInterface.onValuesUpdated();\n                        }\n                        dismissBackgroundDialog();\n                        return true;\n                    }\n                })\n                .show();\n    }\n\n    public void showBackgroundDialog() {\n        String[] availableBackgrounds = getResources().getStringArray(R.array.backgrounds);\n        final ArrayList<String> backgroundNames = new ArrayList<>();\n        for (int i = 0; i < availableBackgrounds.length; i++) {\n            backgroundNames.add(availableBackgrounds[i]);\n        }\n        String selectedBackground = mSettings.getString(Settings.KEY_BACKGROUND);\n        int selectedIndex = backgroundNames.indexOf(selectedBackground);\n        mBackgroundDialog = new MaterialDialog.Builder(SettingsActivity.this)\n                .title(R.string.setting_background)\n                .items(R.array.backgrounds)\n                .alwaysCallSingleChoiceCallback()\n                .itemsCallbackSingleChoice(selectedIndex, new MaterialDialog.ListCallbackSingleChoice() {\n                    @Override\n                    public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {\n                        String selection = backgroundNames.get(which);\n                        if (selection.equals(\"Wallpaper\")) {\n                            mSettings.save(Settings.KEY_BACKGROUND, selection);\n                            sendBackgroundChangedBroadcast();\n                            if (mSettingsInterface != null) {\n                                mSettingsInterface.onValuesUpdated();\n                            }\n                            dismissBackgroundDialog();\n                            showWallpaperPicker();\n                        } else if (selection.equals(\"Color\")) {\n                            dismissBackgroundDialog();\n                            showBackgroundColorDialog();\n                        }\n                        return true;\n                    }\n                })\n                .show();\n    }\n\n    public void showWallpaperPicker() {\n        Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);\n        startActivity(Intent.createChooser(intent, \"Select Wallpaper\"));\n    }\n\n    public void showBackgroundColorDialog() {\n        mBackgroundColorDialog = new ColorChooserDialog.Builder(this, R.string.setting_background_color)\n                .titleSub(R.string.setting_background_color)\n                .accentMode(false)\n                .doneButton(com.afollestad.materialdialogs.commons.R.string.md_done_label)\n                .cancelButton(com.afollestad.materialdialogs.commons.R.string.md_cancel_label)\n                .backButton(com.afollestad.materialdialogs.commons.R.string.md_back_label)\n                .preselect(Color.parseColor(mSettings.getString(Settings.KEY_BACKGROUND_COLOR)))\n                .dynamicButtonColor(false)\n                .allowUserColorInputAlpha(false)\n                .tag(COLOR_TAG_BACKGROUND)\n                .show(this);\n    }\n\n    public void showHighlightColorDialog() {\n        mHighlightColorDialog = new ColorChooserDialog.Builder(this, R.string.setting_highlight_color)\n                .titleSub(R.string.setting_highlight_color)\n                .accentMode(true)\n                .doneButton(com.afollestad.materialdialogs.commons.R.string.md_done_label)\n                .cancelButton(com.afollestad.materialdialogs.commons.R.string.md_cancel_label)\n                .backButton(com.afollestad.materialdialogs.commons.R.string.md_back_label)\n                .preselect(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)))\n                .dynamicButtonColor(false)\n                .allowUserColorInputAlpha(false)\n                .tag(COLOR_TAG_HIGHLIGHT)\n                .show(this);\n    }\n\n    @Override\n    public void onColorSelection(@NonNull ColorChooserDialog dialog, @ColorInt int selectedColor) {\n        String hexColor = String.format(\"#%06X\", selectedColor);\n        if (dialog.tag().equals(COLOR_TAG_BACKGROUND)) {\n            mSettings.save(Settings.KEY_BACKGROUND, \"Color\");\n            mSettings.save(Settings.KEY_BACKGROUND_COLOR, hexColor);\n            sendBackgroundChangedBroadcast();\n        } else if (dialog.tag().equals(COLOR_TAG_HIGHLIGHT)) {\n            mSettings.save(Settings.KEY_HIGHLIGHT_COLOR, hexColor);\n        }\n        if (mSettingsInterface != null) {\n            mSettingsInterface.onValuesUpdated();\n        }\n    }\n\n    @Override\n    public void onColorChooserDismissed(@NonNull ColorChooserDialog dialog) {\n    }\n\n    private void dismissSortTypeDialog() {\n        if (mSortTypeDialog != null && mSortTypeDialog.isShowing()) {\n            mSortTypeDialog.dismiss();\n        }\n    }\n\n    private void dismissIconPackDialog() {\n        if (mIconPackDialog != null && mIconPackDialog.isShowing()) {\n            mIconPackDialog.dismiss();\n        }\n    }\n\n    private void dismissNightModeDialog() {\n        if (mNightModeDialog != null && mNightModeDialog.isShowing()) {\n            mNightModeDialog.dismiss();\n        }\n    }\n\n    private void dismissBackgroundDialog() {\n        if (mBackgroundDialog != null && mBackgroundDialog.isShowing()) {\n            mBackgroundDialog.dismiss();\n        }\n    }\n\n    private void dismissAllDialogs() {\n        dismissSortTypeDialog();\n        dismissIconPackDialog();\n        dismissNightModeDialog();\n        dismissBackgroundDialog();\n        // Color dialogs do not need to be dismissed\n    }\n\n    @Override\n    protected void onDestroy() {\n        dismissAllDialogs();\n        LoadedObservable.getInstance().deleteObserver(this);\n        super.onDestroy();\n    }\n\n    @Override\n    public void onBackPressed() {\n        finish();\n    }\n\n    @Override\n    public void finish() {\n        super.finish();\n        overridePendingTransition(R.anim.fade_in, R.anim.fade_out);\n    }\n\n    private class FragmentPagerAdapter extends FragmentStatePagerAdapter {\n\n        private static final int NUM_PAGES = 3;\n\n        private Context mContext;\n\n        public FragmentPagerAdapter(FragmentManager fragmentManager, Context context) {\n            super(fragmentManager);\n            mContext = context;\n        }\n\n        @Override\n        public Fragment getItem(int position) {\n            switch (position) {\n                case 0:\n                    return LensFragment.newInstance();\n                case 1:\n                    return AppsFragment.newInstance();\n                case 2:\n                    return SettingsFragment.newInstance();\n            }\n            return new Fragment();\n        }\n\n        @Override\n        public int getCount() {\n            return NUM_PAGES;\n        }\n\n        @Override\n        public CharSequence getPageTitle(int position) {\n            switch (position) {\n                case 0:\n                    return mContext.getResources().getString(R.string.tab_lens);\n                case 1:\n                    return mContext.getResources().getString(R.string.tab_apps);\n                case 2:\n                    return mContext.getResources().getString(R.string.tab_settings);\n            }\n            return super.getPageTitle(position);\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/ui/SettingsFragment.java",
    "content": "package nickrout.lenslauncher.ui;\n\nimport android.content.Context;\nimport android.graphics.Color;\nimport android.graphics.drawable.GradientDrawable;\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.support.v4.app.Fragment;\nimport android.support.v7.widget.SwitchCompat;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.CompoundButton;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport butterknife.OnClick;\nimport nickrout.lenslauncher.R;\nimport nickrout.lenslauncher.util.LauncherUtil;\nimport nickrout.lenslauncher.util.NightModeUtil;\nimport nickrout.lenslauncher.util.Settings;\n\n/**\n * Created by nicholasrout on 2016/06/08.\n */\npublic class SettingsFragment extends Fragment implements SettingsActivity.SettingsInterface {\n\n    private static final String TAG = \"SettingsFragment\";\n\n    @OnClick(R.id.layout_home_launcher)\n    public void onHomeLauncherClick() {\n        showHomeLauncherChooser();\n    }\n\n    @BindView(R.id.text_view_selected_home_launcher)\n    TextView mHomeLauncherTextView;\n\n    @OnClick(R.id.layout_icon_pack)\n    public void onIconPackClick() {\n        showIconPackDialog();\n    }\n\n    @BindView(R.id.text_view_selected_icon_pack)\n    TextView mIconPackTextView;\n\n    @OnClick(R.id.layout_night_mode)\n    public void onNightModeClick() {\n        showNightModeChooser();\n    }\n\n    @BindView(R.id.text_view_selected_night_mode)\n    TextView mNightModeTextView;\n\n    @OnClick(R.id.layout_background)\n    public void onBackgroundClick() {\n        showBackgroundDialog();\n    }\n\n    @BindView(R.id.text_view_selected_background)\n    TextView mBackgroundTextView;\n\n    @BindView(R.id.image_view_selected_background_color)\n    ImageView mBackgroundColorImageView;\n\n    @OnClick(R.id.layout_highlight_color)\n    public void onHighlightColorClick() {\n        showHighlightColorDialog();\n    }\n\n    @BindView(R.id.text_view_selected_highlight_color)\n    TextView mHighlightColorTextView;\n\n    @BindView(R.id.image_view_selected_highlight_color)\n    ImageView mHighlightColorImageView;\n\n    @BindView(R.id.switch_vibrate_app_hover)\n    SwitchCompat mVibrateAppHover;\n\n    @BindView(R.id.switch_vibrate_app_launch)\n    SwitchCompat mVibrateAppLaunch;\n\n    @BindView(R.id.switch_show_name_app_hover)\n    SwitchCompat mShowNameAppHover;\n\n    @BindView(R.id.switch_show_new_app_tag)\n    SwitchCompat mShowNewAppTag;\n\n    @BindView(R.id.switch_show_touch_selection)\n    SwitchCompat mShowTouchSelection;\n\n    private Settings mSettings;\n\n    public SettingsFragment() {\n    }\n\n    public static SettingsFragment newInstance() {\n        SettingsFragment settingsFragment = new SettingsFragment();\n        // Include potential bundle extras here\n        return settingsFragment;\n    }\n\n    @Nullable\n    @Override\n    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {\n        View view = inflater.inflate(R.layout.fragment_settings, container, false);\n        ButterKnife.bind(this, view);\n        mSettings = new Settings(getActivity());\n        setupViews();\n        assignValues();\n        return view;\n    }\n\n    @Override\n    public void onAttach(Context context) {\n        super.onAttach(context);\n        if (getActivity() != null && getActivity() instanceof SettingsActivity) {\n            ((SettingsActivity) getActivity()).setSettingsInterface(this);\n        }\n    }\n\n    private void setupViews() {\n        mVibrateAppHover.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {\n            @Override\n            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {\n                mSettings.save(Settings.KEY_VIBRATE_APP_HOVER, isChecked);\n            }\n        });\n        mVibrateAppLaunch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {\n            @Override\n            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {\n                mSettings.save(Settings.KEY_VIBRATE_APP_LAUNCH, isChecked);\n            }\n        });\n        mShowNameAppHover.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {\n            @Override\n            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {\n                mSettings.save(Settings.KEY_SHOW_NAME_APP_HOVER, isChecked);\n            }\n        });\n        mShowNewAppTag.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {\n            @Override\n            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {\n                mSettings.save(Settings.KEY_SHOW_NEW_APP_TAG, isChecked);\n            }\n        });\n        mShowTouchSelection.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {\n            @Override\n            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {\n                mSettings.save(Settings.KEY_SHOW_TOUCH_SELECTION, isChecked);\n            }\n        });\n    }\n\n    private void assignValues() {\n        mIconPackTextView.setText(mSettings.getString(Settings.KEY_ICON_PACK_LABEL_NAME));\n        String highlightColor = \"#\" + mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR).substring(3);\n        String homeLauncher = \"\";\n        if (getActivity() != null) {\n            homeLauncher = LauncherUtil.getHomeLauncherName(getActivity().getApplication());\n        }\n        mHomeLauncherTextView.setText(homeLauncher);\n        mNightModeTextView.setText(NightModeUtil.getNightModeDisplayName(mSettings.getNightMode()));\n        if (mSettings.getString(Settings.KEY_BACKGROUND).equals(\"Color\")) {\n            String backgroundColor = \"#\" + mSettings.getString(Settings.KEY_BACKGROUND_COLOR).substring(3);\n            mBackgroundTextView.setText(backgroundColor);\n            mBackgroundColorImageView.setVisibility(View.VISIBLE);\n            GradientDrawable backgroundColorDrawable = new GradientDrawable();\n            backgroundColorDrawable.setColor(Color.parseColor(mSettings.getString(Settings.KEY_BACKGROUND_COLOR)));\n            backgroundColorDrawable.setCornerRadius(getResources().getDimension(R.dimen.radius_highlight_color_switch));\n            mBackgroundColorImageView.setImageDrawable(backgroundColorDrawable);\n        } else {\n            mBackgroundTextView.setText(mSettings.getString(Settings.KEY_BACKGROUND));\n            mBackgroundColorImageView.setVisibility(View.GONE);\n        }\n        mHighlightColorTextView.setText(highlightColor);\n        GradientDrawable highlightColorDrawable = new GradientDrawable();\n        highlightColorDrawable.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));\n        highlightColorDrawable.setCornerRadius(getResources().getDimension(R.dimen.radius_highlight_color_switch));\n        mHighlightColorImageView.setImageDrawable(highlightColorDrawable);\n        mVibrateAppHover.setChecked(mSettings.getBoolean(Settings.KEY_VIBRATE_APP_HOVER));\n        mVibrateAppLaunch.setChecked(mSettings.getBoolean(Settings.KEY_VIBRATE_APP_LAUNCH));\n        mShowNameAppHover.setChecked(mSettings.getBoolean(Settings.KEY_SHOW_NAME_APP_HOVER));\n        mShowNewAppTag.setChecked(mSettings.getBoolean(Settings.KEY_SHOW_NEW_APP_TAG));\n        mShowTouchSelection.setChecked(mSettings.getBoolean(Settings.KEY_SHOW_TOUCH_SELECTION));\n    }\n\n    private void showIconPackDialog() {\n        if (getActivity() != null && getActivity() instanceof SettingsActivity) {\n            ((SettingsActivity) getActivity()).showIconPackDialog();\n        }\n    }\n\n    private void showHomeLauncherChooser() {\n        if (getActivity() != null && getActivity() instanceof SettingsActivity) {\n            ((SettingsActivity) getActivity()).showHomeLauncherChooser();\n        }\n    }\n\n    private void showNightModeChooser() {\n        if (getActivity() != null && getActivity() instanceof SettingsActivity) {\n            ((SettingsActivity) getActivity()).showNightModeChooser();\n        }\n    }\n\n    private void showBackgroundDialog() {\n        if (getActivity() != null && getActivity() instanceof SettingsActivity) {\n            ((SettingsActivity) getActivity()).showBackgroundDialog();\n        }\n    }\n\n    private void showHighlightColorDialog() {\n        if (getActivity() != null && getActivity() instanceof SettingsActivity) {\n            ((SettingsActivity) getActivity()).showHighlightColorDialog();\n        }\n    }\n\n    @Override\n    public void onDefaultsReset() {\n        resetToDefault();\n        assignValues();\n    }\n\n    @Override\n    public void onValuesUpdated() {\n        assignValues();\n    }\n\n    private void resetToDefault() {\n        mSettings.save(Settings.KEY_VIBRATE_APP_HOVER, Settings.DEFAULT_VIBRATE_APP_HOVER);\n        mSettings.save(Settings.KEY_VIBRATE_APP_LAUNCH, Settings.DEFAULT_VIBRATE_APP_LAUNCH);\n        mSettings.save(Settings.KEY_SHOW_NAME_APP_HOVER, Settings.DEFAULT_SHOW_NAME_APP_HOVER);\n        mSettings.save(Settings.KEY_SHOW_TOUCH_SELECTION, Settings.DEFAULT_SHOW_TOUCH_SELECTION);\n        mSettings.save(Settings.KEY_SHOW_NEW_APP_TAG, Settings.DEFAULT_SHOW_NEW_APP_TAG);\n        mSettings.save(Settings.KEY_BACKGROUND, Settings.DEFAULT_BACKGROUND);\n        mSettings.save(Settings.KEY_BACKGROUND_COLOR, Settings.DEFAULT_BACKGROUND_COLOR);\n        mSettings.save(Settings.KEY_HIGHLIGHT_COLOR, Settings.DEFAULT_HIGHLIGHT_COLOR);\n        mSettings.save(Settings.KEY_ICON_PACK_LABEL_NAME, Settings.DEFAULT_ICON_PACK_LABEL_NAME);\n        mSettings.save(Settings.KEY_NIGHT_MODE, Settings.DEFAULT_NIGHT_MODE);\n        if (getActivity() != null && getActivity() instanceof SettingsActivity) {\n            ((SettingsActivity) getActivity()).sendNightModeBroadcast();\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/util/AppSorter.java",
    "content": "package nickrout.lenslauncher.util;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\n\nimport nickrout.lenslauncher.R;\nimport nickrout.lenslauncher.model.App;\nimport nickrout.lenslauncher.model.AppPersistent;\n\n/**\n * Created by nicholasrout on 2016/05/28.\n */\npublic class AppSorter {\n\n    public enum SortType {\n        LABEL_ASCENDING(R.string.setting_sort_type_label_ascending),\n        LABEL_DESCENDING(R.string.setting_sort_type_label_descending),\n        INSTALL_DATE_ASCENDING(R.string.setting_sort_type_install_date_ascending),\n        INSTALL_DATE_DESCENDING(R.string.setting_sort_type_install_date_descending),\n        ICON_COLOR_ASCENDING(R.string.setting_sort_type_icon_color_ascending),\n        ICON_COLOR_DESCENDING(R.string.setting_sort_type_icon_color_descending),\n        OPEN_COUNT_ASCENDING(R.string.setting_sort_type_open_count_ascending),\n        OPEN_COUNT_DESCENDING(R.string.setting_sort_type_open_count_descending);\n\n        int mDisplayNameResId;\n\n        SortType(int displayNameResId) {\n            mDisplayNameResId = displayNameResId;\n        }\n\n        public int getDisplayNameResId() {\n            return mDisplayNameResId;\n        }\n    }\n\n    public static void sort(ArrayList<App> apps, SortType sortType) {\n        switch (sortType) {\n            case LABEL_ASCENDING:\n                sortByLabelAscending(apps);\n                break;\n            case LABEL_DESCENDING:\n                sortByLabelDescending(apps);\n                break;\n            case INSTALL_DATE_ASCENDING:\n                sortByInstallDateAscending(apps);\n                break;\n            case INSTALL_DATE_DESCENDING:\n                sortByInstallDateDescending(apps);\n                break;\n            case OPEN_COUNT_ASCENDING:\n                sortByOpenCountAscending(apps);\n                break;\n            case OPEN_COUNT_DESCENDING:\n                sortByOpenCountDescending(apps);\n                break;\n            case ICON_COLOR_ASCENDING:\n                sortByIconColorAscending(apps);\n                break;\n            case ICON_COLOR_DESCENDING:\n                sortByIconColorDescending(apps);\n                break;\n            default:\n                sortByLabelAscending(apps);\n                break;\n        }\n    }\n\n    private static void sortByLabelAscending(ArrayList<App> apps) {\n        Collections.sort(apps, new Comparator<App>() {\n            @Override\n            public int compare(App a1, App a2) {\n                return (a1.getLabel().toString()).compareToIgnoreCase(a2.getLabel().toString());\n            }\n        });\n    }\n\n    private static void sortByLabelDescending(ArrayList<App> apps) {\n        sortByLabelAscending(apps);\n        Collections.reverse(apps);\n    }\n\n    private static void sortByInstallDateAscending(ArrayList<App> apps) {\n        Collections.sort(apps, new Comparator<App>() {\n            @Override\n            public int compare(App a1, App a2) {\n                if (a1.getInstallDate() > a2.getInstallDate()) {\n                    return -1;\n                } else if (a1.getInstallDate() < a2.getInstallDate()) {\n                    return +1;\n                }\n                return 0;\n            }\n        });\n    }\n\n    private static void sortByInstallDateDescending(ArrayList<App> apps) {\n        sortByInstallDateAscending(apps);\n        Collections.reverse(apps);\n    }\n\n    private static void sortByOpenCountAscending(ArrayList<App> apps) {\n        Collections.sort(apps, new Comparator<App>() {\n            @Override\n            public int compare(App a1, App a2) {\n                long a1OpenCount =\n                        AppPersistent.getAppOpenCount(a1.getPackageName().toString(), a1.getName().toString());\n                long a2OpenCount =\n                        AppPersistent.getAppOpenCount(a2.getPackageName().toString(), a2.getName().toString());\n                if (a1OpenCount > a2OpenCount) {\n                    return -1;\n                } else if (a1OpenCount < a2OpenCount) {\n                    return +1;\n                }\n                return 0;\n            }\n        });\n    }\n\n    private static void sortByOpenCountDescending(ArrayList<App> apps) {\n        sortByOpenCountAscending(apps);\n        Collections.reverse(apps);\n    }\n\n    private static void sortByIconColorAscending(ArrayList<App> apps) {\n        Collections.sort(apps, new Comparator<App>() {\n            @Override\n            public int compare(App a1, App a2) {\n                float a1HSVColor = ColorUtil.getHueColorFromApp(a1);\n                float a2HSVColor = ColorUtil.getHueColorFromApp(a2);\n\n                if (a1HSVColor > a2HSVColor) {\n                    return -1;\n                } else if (a1HSVColor < a2HSVColor) {\n                    return +1;\n                }\n                return 0;\n            }\n        });\n    }\n\n    private static void sortByIconColorDescending(ArrayList<App> apps) {\n        sortByIconColorAscending(apps);\n        Collections.reverse(apps);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/util/AppUtil.java",
    "content": "package nickrout.lenslauncher.util;\n\nimport android.app.Application;\nimport android.content.ActivityNotFoundException;\nimport android.content.ComponentName;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.pm.PackageManager;\nimport android.content.pm.ResolveInfo;\nimport android.graphics.Bitmap;\nimport android.graphics.Rect;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.support.v4.app.ActivityOptionsCompat;\nimport android.support.v4.content.ContextCompat;\nimport android.view.View;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport nickrout.lenslauncher.R;\nimport nickrout.lenslauncher.background.BroadcastReceivers;\nimport nickrout.lenslauncher.model.App;\nimport nickrout.lenslauncher.model.AppPersistent;\n\n/**\n * Created by nickrout on 2016/04/02.\n */\npublic class AppUtil {\n\n    private static final String TAG = AppUtil.class.getSimpleName();\n\n    // Get all available apps for launcher\n    public static ArrayList<App> getApps(\n            PackageManager packageManager, Context context, Application application,\n            String iconPackLabelName, AppSorter.SortType sortType) {\n        ArrayList<App> apps = new ArrayList<>();\n        Intent intent = new Intent(Intent.ACTION_MAIN, null);\n        intent.addCategory(Intent.CATEGORY_LAUNCHER);\n        List<ResolveInfo> availableActivities = null;\n        try {\n            availableActivities = packageManager.queryIntentActivities(intent, 0);\n        } catch (RuntimeException e) {\n            e.printStackTrace();\n            Toast.makeText(context, R.string.error_too_many_apps, Toast.LENGTH_SHORT).show();\n        }\n        if (availableActivities != null) {\n            IconPackManager.IconPack selectedIconPack = null;\n            ArrayList<IconPackManager.IconPack> iconPacks = new IconPackManager().getAvailableIconPacksWithIcons(true, application);\n\n            for (IconPackManager.IconPack iconPack : iconPacks) {\n                if (iconPack.mName.equals(iconPackLabelName))\n                    selectedIconPack = iconPack;\n            }\n\n            for (int i = 0; i < availableActivities.size(); i++) {\n                ResolveInfo resolveInfo = availableActivities.get(i);\n                App app = new App();\n                app.setId(i);\n                try {\n                    app.setInstallDate(packageManager.getPackageInfo(resolveInfo.activityInfo.packageName, 0).firstInstallTime);\n                } catch (PackageManager.NameNotFoundException e) {\n                    app.setInstallDate(0);\n                }\n                app.setLabel(resolveInfo.loadLabel(packageManager));\n                app.setPackageName(resolveInfo.activityInfo.packageName);\n                app.setName(resolveInfo.activityInfo.name);\n                app.setIconResId(resolveInfo.activityInfo.getIconResource());\n                Bitmap defaultBitmap = BitmapUtil.packageNameToBitmap(\n                        context, packageManager, resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.getIconResource());\n                if (selectedIconPack != null)\n                    app.setIcon(selectedIconPack.getIconForPackage(app.getPackageName().toString(), defaultBitmap));\n                else\n                    app.setIcon(defaultBitmap);\n                app.setPaletteColor(ColorUtil.getPaletteColorFromApp(app));\n                apps.add(app);\n            }\n        }\n        AppSorter.sort(apps, sortType);\n        return apps;\n    }\n\n    // Launch apps, for launcher :-P\n    public static void launchComponent(Context context, String packageName, String name, View view, Rect bounds) {\n        if (packageName != null && name != null) {\n            Intent componentIntent = new Intent();\n            componentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\n            componentIntent.setComponent(new ComponentName(packageName, name));\n            if (!packageName.equals(\"nickrout.lenslauncher\")) {\n                componentIntent.setAction(Intent.ACTION_MAIN);\n            }\n            componentIntent.addCategory(Intent.CATEGORY_LAUNCHER);\n            try {\n                // Launch Component\n                ContextCompat.startActivity(context, componentIntent, getLauncherOptionsBundle(context, view, bounds));\n                // Increment app open count\n                AppPersistent.incrementAppCount(packageName, name);\n                // Resort apps (if open count selected)\n                Settings settings = new Settings(context);\n                if (settings.getSortType() == AppSorter.SortType.OPEN_COUNT_ASCENDING ||\n                        settings.getSortType() == AppSorter.SortType.OPEN_COUNT_DESCENDING) {\n                    Intent editAppsIntent = new Intent(context, BroadcastReceivers.AppsEditedReceiver.class);\n                    context.sendBroadcast(editAppsIntent);\n                }\n            } catch (ActivityNotFoundException e) {\n                Toast.makeText(context, R.string.error_app_not_found, Toast.LENGTH_SHORT).show();\n            }\n        } else {\n            Toast.makeText(context, R.string.error_app_not_found, Toast.LENGTH_SHORT).show();\n        }\n    }\n\n    private static Bundle getLauncherOptionsBundle(Context context, View source, Rect bounds) {\n        Bundle optionsBundle = null;\n        if (source != null) {\n            ActivityOptionsCompat options;\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && bounds != null) {\n                // Clip reveal animation for Marshmallow and above\n                options = ActivityOptionsCompat.makeClipRevealAnimation(source, bounds.left, bounds.top, bounds.width(), bounds.height());\n            } else {\n                // Fade animation otherwise\n                options = ActivityOptionsCompat.makeCustomAnimation(context, R.anim.fade_in, R.anim.fade_out);\n            }\n            optionsBundle = options.toBundle();\n        }\n        return optionsBundle;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/util/BitmapUtil.java",
    "content": "package nickrout.lenslauncher.util;\n\nimport android.content.Context;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageManager;\nimport android.content.res.Resources;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.graphics.Canvas;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.Drawable;\n\n/**\n * Created by nickrout on 2016/04/02.\n */\npublic class BitmapUtil {\n\n    // Old method - does not allow for adding options i.e. lower quality\n    // Source: http://stackoverflow.com/questions/3035692/how-to-convert-a-drawable-to-a-bitmap\n    public static Bitmap drawableToBitmap (Drawable drawable) {\n        Bitmap bitmap = null;\n\n        if (drawable instanceof BitmapDrawable) {\n            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;\n            bitmapDrawable.setAntiAlias(true);\n            bitmapDrawable.setDither(true);\n            bitmapDrawable.setTargetDensity(Integer.MAX_VALUE);\n            if(bitmapDrawable.getBitmap() != null) {\n                return bitmapDrawable.getBitmap();\n            }\n        }\n\n        if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {\n            bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel\n        } else {\n            bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);\n        }\n\n        Canvas canvas = new Canvas(bitmap);\n        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());\n        drawable.draw(canvas);\n        return bitmap;\n    }\n\n    // Get bitmap from resource id, with quality options\n    public static Bitmap resIdToBitmap(Resources res, int resId) {\n        BitmapFactory.Options options = new BitmapFactory.Options();\n        options.inScaled = false;\n        options.inDither = false;\n        options.inPreferredConfig = Bitmap.Config.ARGB_8888;\n        options.inPreferQualityOverSpeed = true;\n        try {\n            return BitmapFactory.decodeResource(res, resId, options);\n        } catch (OutOfMemoryError e1) {\n            e1.printStackTrace();\n            return null;\n        }\n    }\n\n    // Get res id from app package name\n    public static int packageNameToResId(PackageManager packageManager, String packageName) {\n        try {\n            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA);\n            return applicationInfo.icon;\n        } catch (PackageManager.NameNotFoundException e) {\n            e.printStackTrace();\n            return -1;\n        }\n    }\n\n    // Get bitmap from app package name\n    public static Bitmap packageNameToBitmap(PackageManager packageManager, String packageName) {\n        try {\n            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA);\n            Resources resources = packageManager.getResourcesForApplication(applicationInfo);\n            int appIconResId = applicationInfo.icon;\n            return resIdToBitmap(resources, appIconResId);\n        } catch (PackageManager.NameNotFoundException e) {\n            e.printStackTrace();\n            return null;\n        }\n    }\n\n    // Get bitmap from app package name (with res id)\n    public static Bitmap packageNameToBitmap(Context context, PackageManager packageManager, String packageName, int resId) {\n        try {\n            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA);\n            Resources resources = packageManager.getResourcesForApplication(applicationInfo);\n            Bitmap bitmap = resIdToBitmap(resources, resId);\n            if (bitmap == null) {\n                Drawable drawable = packageManager.getApplicationIcon(packageName);\n                if (drawable != null) {\n                    bitmap = drawableToBitmap(drawable);\n                }\n            }\n            return bitmap;\n        } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {\n            e.printStackTrace();\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/util/ColorUtil.java",
    "content": "package nickrout.lenslauncher.util;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Color;\nimport android.support.annotation.ColorInt;\nimport android.support.v7.graphics.Palette;\n\nimport nickrout.lenslauncher.model.App;\n\n/**\n * Created by nicholasrout on 2016/05/28.\n */\npublic class ColorUtil {\n\n    public static @ColorInt int getPaletteColorFromApp(App app) {\n        return getPaletteColorFromBitmap(app.getIcon());\n    }\n\n    public static @ColorInt int getPaletteColorFromBitmap(Bitmap bitmap) {\n        Palette palette;\n        try {\n            palette = Palette.from(bitmap).generate();\n        } catch (IllegalArgumentException e) {\n            e.printStackTrace();\n            return Color.BLACK;\n        }\n        if (palette.getSwatches().size() > 0) {\n            int swatchIndex = 0;\n            for (int i = 1; i < palette.getSwatches().size(); i++) {\n                if (palette.getSwatches().get(i).getPopulation()\n                        > palette.getSwatches().get(swatchIndex).getPopulation()) {\n                    swatchIndex = i;\n                }\n            }\n            return palette.getSwatches().get(swatchIndex).getRgb();\n        } else {\n            return Color.BLACK;\n        }\n    }\n\n    public static float getHueColorFromApp(App app) {\n        return getHueColorFromColor(app.getPaletteColor());\n    }\n\n    public static float getHueColorFromColor(@ColorInt int color) {\n        float[] hsvValues = new float[3];\n        Color.colorToHSV(color, hsvValues);\n        return hsvValues[0];\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/util/IconPackManager.java",
    "content": "package nickrout.lenslauncher.util;\n\n/**\n * Created by rish on 22/5/16.\n */\n\nimport android.app.Application;\nimport android.content.Intent;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageManager;\nimport android.content.pm.ResolveInfo;\nimport android.content.res.Resources;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.PorterDuff;\nimport android.graphics.PorterDuffXfermode;\nimport android.graphics.Rect;\nimport android.graphics.RectF;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.Drawable;\nimport android.support.annotation.ColorInt;\nimport android.util.Log;\n\nimport org.xmlpull.v1.XmlPullParser;\nimport org.xmlpull.v1.XmlPullParserException;\nimport org.xmlpull.v1.XmlPullParserFactory;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Locale;\n\nimport nickrout.lenslauncher.R;\n\npublic class IconPackManager {\n\n    private static final String TAG = \"IconPackManager\";\n\n    private Application mApplication;\n\n    public class IconPack {\n\n        public IconPack() {\n            mPaint = new Paint();\n            mPaint.setAntiAlias(true);\n            mPaint.setStyle(Paint.Style.FILL);\n            mPaint.setFilterBitmap(true);\n            mPaint.setDither(true);\n        }\n\n        public String mPackageName;\n        public String mName;\n\n        private boolean mLoaded = false;\n        private HashMap<String, String> mPackagesDrawables = new HashMap<String, String>();\n\n        private List<Bitmap> mBackImages = new ArrayList<Bitmap>();\n        private Bitmap mMaskImage = null;\n        private Bitmap mFrontImage = null;\n        private float mFactor = 1.0f;\n\n        private Paint mPaint;\n\n        Resources mIconPackRes = null;\n\n        public void load() {\n            // Load appfilter.xml from the icon pack package\n            PackageManager pm = mApplication.getPackageManager();\n            try {\n                XmlPullParser xpp = null;\n                mIconPackRes = pm.getResourcesForApplication(mPackageName);\n                int appfilterid = mIconPackRes.getIdentifier(\"appfilter\", \"xml\", mPackageName);\n                if (appfilterid > 0) {\n                    xpp = mIconPackRes.getXml(appfilterid);\n                } else {\n                    // No resource found, try to open it from assets folder\n                    try {\n                        InputStream appfilterstream = mIconPackRes.getAssets().open(\"appfilter.xml\");\n\n                        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();\n                        factory.setNamespaceAware(true);\n                        xpp = factory.newPullParser();\n                        xpp.setInput(appfilterstream, \"utf-8\");\n                    } catch (IOException e1) {\n                        Log.d(TAG, \"No appfilter.xml file\");\n                    }\n                }\n\n                if (xpp != null) {\n                    int eventType = xpp.getEventType();\n                    while (eventType != XmlPullParser.END_DOCUMENT) {\n                        if (eventType == XmlPullParser.START_TAG) {\n                            if (xpp.getName().equals(\"iconback\")) {\n                                for (int i = 0; i < xpp.getAttributeCount(); i++) {\n                                    if (xpp.getAttributeName(i).startsWith(\"img\")) {\n                                        String drawableName = xpp.getAttributeValue(i);\n                                        Bitmap iconback = loadBitmap(drawableName);\n                                        if (iconback != null)\n                                            mBackImages.add(iconback);\n                                    }\n                                }\n                            } else if (xpp.getName().equals(\"iconmask\")) {\n                                if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals(\"img1\")) {\n                                    String drawableName = xpp.getAttributeValue(0);\n                                    mMaskImage = loadBitmap(drawableName);\n                                }\n                            } else if (xpp.getName().equals(\"iconupon\")) {\n                                if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals(\"img1\")) {\n                                    String drawableName = xpp.getAttributeValue(0);\n                                    mFrontImage = loadBitmap(drawableName);\n                                }\n                            } else if (xpp.getName().equals(\"scale\")) {\n                                if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals(\"factor\")) {\n                                    try {\n                                        mFactor = Float.valueOf(xpp.getAttributeValue(0));\n                                    } catch (NumberFormatException e) {\n                                        mFactor = 1.0f;\n                                        e.printStackTrace();\n                                    }\n                                }\n                            } else if (xpp.getName().equals(\"item\")) {\n                                String componentName = null;\n                                String drawableName = null;\n\n                                for (int i = 0; i < xpp.getAttributeCount(); i++) {\n                                    if (xpp.getAttributeName(i).equals(\"component\")) {\n                                        componentName = xpp.getAttributeValue(i);\n                                    } else if (xpp.getAttributeName(i).equals(\"drawable\")) {\n                                        drawableName = xpp.getAttributeValue(i);\n                                    }\n                                }\n                                if (!mPackagesDrawables.containsKey(componentName))\n                                    mPackagesDrawables.put(componentName, drawableName);\n                            }\n                        }\n                        eventType = xpp.next();\n                    }\n                }\n                mLoaded = true;\n            } catch (PackageManager.NameNotFoundException e) {\n                Log.d(TAG, \"Cannot load icon pack\");\n            } catch (XmlPullParserException e) {\n                Log.d(TAG, \"Cannot parse icon pack appfilter.xml\");\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n\n        private Bitmap loadBitmap(String drawableName) {\n            int id = mIconPackRes.getIdentifier(drawableName, \"drawable\", mPackageName);\n            if (id > 0) {\n                Drawable bitmap = mIconPackRes.getDrawable(id);\n                if (bitmap instanceof BitmapDrawable)\n                    return ((BitmapDrawable) bitmap).getBitmap();\n            }\n            return null;\n        }\n\n        public Bitmap getIconForPackage(String appPackageName, Bitmap defaultBitmap) {\n            if (!mLoaded) {\n                load();\n            }\n\n            PackageManager pm = mApplication.getPackageManager();\n            Intent launchIntent = pm.getLaunchIntentForPackage(appPackageName);\n            String componentName = null;\n            if (launchIntent != null)\n                componentName = pm.getLaunchIntentForPackage(appPackageName).getComponent().toString();\n            String drawable = mPackagesDrawables.get(componentName);\n            if (drawable != null) {\n                Bitmap bitmap = loadBitmap(drawable);\n                if (bitmap == null) {\n                    return generateBitmap(defaultBitmap);\n                }\n                return bitmap;\n            } else {\n                // Try to get a resource with the component filename\n                if (componentName != null) {\n                    int start = componentName.indexOf(\"{\") + 1;\n                    int end = componentName.indexOf(\"}\", start);\n                    if (end > start) {\n                        drawable = componentName.substring(start, end).toLowerCase(Locale.getDefault()).replace(\".\", \"_\").replace(\"/\", \"_\");\n                        if (mIconPackRes.getIdentifier(drawable, \"drawable\", mPackageName) > 0)\n                            return loadBitmap(drawable);\n                    }\n                }\n            }\n            return generateBitmap(defaultBitmap);\n        }\n\n        private Bitmap generateBitmap(Bitmap defaultBitmap) {\n            // No need to go through below process id defaultBitmap is null\n            if (defaultBitmap == null) {\n                return null;\n            }\n            // If no back images, return default app icon\n            if (mBackImages.size() == 0) {\n                return defaultBitmap;\n            }\n            // Get a random back image\n            Bitmap backImage = getMostAppropriateBackImage(defaultBitmap);\n            int backImageWidth = backImage.getWidth();\n            int backImageHeight = backImage.getHeight();\n            // Create a bitmap for the result\n            Bitmap result;\n            try {\n                result = Bitmap.createBitmap(backImageWidth, backImageHeight, Bitmap.Config.ARGB_8888);\n            } catch (OutOfMemoryError e) {\n                e.printStackTrace();\n                return null;\n            }\n            // Instantiate a canvas to combine the icon / background\n            Canvas canvas = new Canvas(result);\n            // Draw the background first\n            canvas.drawBitmap(backImage, 0, 0, null);\n            // Create rects for scaling the default bitmap\n            Rect srcRect = new Rect(\n                    0,\n                    0,\n                    defaultBitmap.getWidth(),\n                    defaultBitmap.getHeight()\n            );\n            float scaledWidth = mFactor * ((float) backImageWidth);\n            float scaledHeight = mFactor * ((float) backImageHeight);\n            RectF destRect = new RectF(\n                    ((float) backImageWidth) / 2.0f - scaledWidth / 2.0f,\n                    ((float) backImageHeight) / 2.0f - scaledHeight / 2.0f,\n                    ((float) backImageWidth) / 2.0f + scaledWidth / 2.0f,\n                    ((float) backImageHeight) / 2.0f + scaledHeight / 2.0f\n            );\n            // Handle mask image\n            if (mMaskImage != null) {\n                // First get mask bitmap\n                Bitmap mask;\n                try {\n                    mask = Bitmap.createBitmap(backImageWidth, backImageHeight, Bitmap.Config.ARGB_8888);\n                } catch (OutOfMemoryError e) {\n                    e.printStackTrace();\n                    return null;\n                }\n                // Make a temp mask canvas\n                Canvas maskCanvas = new Canvas(mask);\n                // Draw the bitmap with mask into the result\n                maskCanvas.drawBitmap(\n                        defaultBitmap, srcRect, destRect, mPaint\n                );\n                mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));\n                maskCanvas.drawBitmap(mMaskImage, 0, 0, mPaint);\n                mPaint.setXfermode(null);\n                canvas.drawBitmap(mask, 0, 0, mPaint);\n            } else {\n                // Draw the scaled bitmap without mask\n                canvas.drawBitmap(\n                        defaultBitmap, srcRect, destRect, mPaint\n                );\n            }\n            // Draw the front image\n            if (mFrontImage != null) {\n                canvas.drawBitmap(mFrontImage, 0, 0, mPaint);\n            }\n            // Return result\n            return result;\n        }\n\n        private Bitmap getMostAppropriateBackImage(Bitmap defaultBitmap) {\n            if (mBackImages.size() == 1) {\n                return mBackImages.get(0);\n            }\n            @ColorInt int defaultPaletteColor = ColorUtil.getPaletteColorFromBitmap(defaultBitmap);\n            float defaultHueColor = ColorUtil.getHueColorFromColor(defaultPaletteColor);\n            float difference = Float.MAX_VALUE;\n            int index = 0;\n            for (int i = 0; i < mBackImages.size(); i++) {\n                @ColorInt int backPaletteColor = ColorUtil.getPaletteColorFromBitmap(mBackImages.get(i));\n                float backHueColor = ColorUtil.getHueColorFromColor(backPaletteColor);\n                if (Math.abs(defaultHueColor - backHueColor) < difference) {\n                    difference = Math.abs(defaultHueColor - backHueColor);\n                    index = i;\n                }\n            }\n            return mBackImages.get(index);\n        }\n    }\n\n    private ArrayList<IconPack> mIconPacks = null;\n\n    public ArrayList<IconPack> getAvailableIconPacksWithIcons(boolean forceReload, Application application) {\n        mApplication = application;\n\n        if (mIconPacks == null || forceReload) {\n            mIconPacks = new ArrayList<>();\n\n            PackageManager pm = mApplication.getPackageManager();\n\n            /**\n             * Currently Lens Launcher supports all icon packs supported by GoLauncher / EX\n             * Create a set by filter the list to contain unique icon packs only\n             */\n            List<ResolveInfo> rinfo = new ArrayList<>();\n            for (String launcher : mApplication.getResources().getStringArray(R.array.icon_pack_launchers)) {\n                rinfo.addAll(pm.queryIntentActivities(new Intent(launcher), PackageManager.GET_META_DATA));\n            }\n\n            for (ResolveInfo ri : rinfo) {\n                IconPack ip = new IconPack();\n                ip.mPackageName = ri.activityInfo.packageName;\n\n                ApplicationInfo ai = null;\n                try {\n                    ai = pm.getApplicationInfo(ip.mPackageName, PackageManager.GET_META_DATA);\n                    ip.mName = mApplication.getPackageManager().getApplicationLabel(ai).toString();\n                    mIconPacks.add(ip);\n                } catch (PackageManager.NameNotFoundException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n        return mIconPacks;\n    }\n}"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/util/LauncherUtil.java",
    "content": "package nickrout.lenslauncher.util;\n\nimport android.app.Application;\nimport android.content.ComponentName;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.pm.PackageManager;\nimport android.content.pm.ResolveInfo;\n\n/**\n * Created by rish on 5/6/16.\n */\npublic class LauncherUtil {\n\n    public static boolean isLauncherDefault(Application application) {\n        final Intent intent = new Intent(Intent.ACTION_MAIN);\n        intent.addCategory(Intent.CATEGORY_HOME);\n        final ResolveInfo res = application.getPackageManager().resolveActivity(intent, 0);\n        if (res.activityInfo == null) {\n            return false;\n        } else if (\"android\".equals(res.activityInfo.packageName)) {\n            return false;\n        } else {\n            if (res.activityInfo.packageName.equals(application.getPackageName())) return true;\n            else\n                return false;\n        }\n    }\n\n    public static String getHomeLauncherName(Application application) {\n        final Intent intent = new Intent(Intent.ACTION_MAIN);\n        intent.addCategory(Intent.CATEGORY_HOME);\n        final ResolveInfo res = application.getPackageManager().resolveActivity(intent, 0);\n        if (res.activityInfo == null) {\n            return \"\";\n        }\n        return res.activityInfo.loadLabel(application.getPackageManager()).toString();\n    }\n\n    public static void resetPreferredLauncherAndOpenChooser(Context context) {\n        PackageManager packageManager = context.getPackageManager();\n        ComponentName componentName = new ComponentName(context, nickrout.lenslauncher.ui.FakeLauncherActivity.class);\n        packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);\n        Intent selector = new Intent(Intent.ACTION_MAIN);\n        selector.addCategory(Intent.CATEGORY_HOME);\n        selector.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\n        context.startActivity(selector);\n        packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, PackageManager.DONT_KILL_APP);\n    }\n}"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/util/LensCalculator.java",
    "content": "package nickrout.lenslauncher.util;\n\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.graphics.RectF;\nimport android.util.DisplayMetrics;\n\nimport nickrout.lenslauncher.model.Grid;\n\n/**\n * Created by nickrout on 2016/04/02.\n */\npublic class LensCalculator {\n\n    // Algorithm for calculating equispaced grid\n    public static Grid calculateGrid(Context context, int screenWidth, int screenHeight, int itemCount) {\n        Grid grid = new Grid();\n        grid.setItemCount(itemCount);\n        int itemCountHorizontal, itemCountVertical;\n        if (itemCount == 0 || itemCount == 1) {\n            itemCountHorizontal = itemCount;\n            itemCountVertical = itemCount;\n        } else {\n            double optimalSquareSize = calculateOptimalSquareSize(screenWidth, screenHeight, itemCount);\n            itemCountHorizontal = (int) Math.ceil(screenWidth / optimalSquareSize);\n            itemCountVertical = (int) Math.ceil((double) itemCount / (double) itemCountHorizontal);\n        }\n        grid.setItemCountHorizontal(itemCountHorizontal);\n        grid.setItemCountVertical(itemCountVertical);\n        Settings settings = new Settings(context);\n        float itemSize = LensCalculator.convertDpToPixel(settings.getFloat(Settings.KEY_ICON_SIZE), context);\n        grid.setItemSize(itemSize);\n        float spacingHorizontal = (((float) screenWidth) - ((float) itemCountHorizontal * itemSize)) / ((float) (itemCountHorizontal + 1));\n        grid.setSpacingHorizontal(spacingHorizontal);\n        float spacingVertical = (((float) screenHeight) - ((float) itemCountVertical * itemSize)) / ((float) (itemCountVertical + 1));\n        grid.setSpacingVertical(spacingVertical);\n        return grid;\n    }\n\n    // Algorithm for calculating optimal square side length given width, height and number of items\n    public static double calculateOptimalSquareSize(int screenWidth, int screenHeight, int itemCount) {\n        // Source: http://math.stackexchange.com/questions/466198/algorithm-to-get-the-maximum-size-of-n-squares-that-fit-into-a-rectangle-with-a\n        double x = (double) screenWidth, y = (double) screenHeight, n = (double) itemCount;\n        double px = Math.ceil(Math.sqrt(n * x / y));\n        double sx, sy;\n        if(Math.floor(px * y / x) * px < n) {\n            sx = y / Math.ceil(px * y / x);\n        } else {\n            sx = x / px;\n        }\n        double py = Math.ceil(Math.sqrt(n * y / x));\n        if(Math.floor(py * x / y) * py < n) {\n            sy = x / Math.ceil(x * py / y);\n        } else {\n            sy = y / py;\n        }\n        return Math.max(sx, sy);\n    }\n\n    // Algorithm for circular distance\n    public static double calculateDistance(float x1, float x2, float y1, float y2) {\n        return Math.sqrt(Math.pow((double) (x2 - x1), 2) + Math.pow((double) (y2 - y1), 2));\n    }\n\n    // Algorithm for determining whether a rect is within a given lens (centered at touchX, touchY)\n    public static boolean isRectWithinLens(RectF rect, float touchX, float touchY, float lensDiameter) {\n        if (rect.left >= touchX - lensDiameter / 2.0f &&\n                rect.right <= touchX + lensDiameter / 2.0f &&\n                rect.top >= touchY - lensDiameter / 2.0f &&\n                rect.bottom <= touchY + lensDiameter / 2.0f) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    // Graphical Fisheye Lens algorithm for shifting\n    public static float shiftPoint(Context context, float lensPosition, float itemPosition, float boundary, float multiplier) {\n        if (lensPosition < 0) {\n            return itemPosition;\n        }\n        Settings settings = new Settings(context);\n        float shiftedPosition;\n        float a = Math.abs(lensPosition - itemPosition);\n        float b = Math.max(lensPosition, boundary - lensPosition);\n        float x = a / b;\n        float d = multiplier * settings.getFloat(Settings.KEY_DISTORTION_FACTOR);\n        float y = ((1.0f + d) * x) / (1.0f + (d * x));\n        float newDistanceFromCenter = b * y;\n        if (lensPosition >= itemPosition) {\n            shiftedPosition = lensPosition - newDistanceFromCenter;\n        } else {\n            shiftedPosition = lensPosition + newDistanceFromCenter;\n        }\n        return shiftedPosition;\n    }\n\n    // Graphical Fisheye Lens algorithm for scaling\n    public static float scalePoint(Context context, float lensPosition, float itemPosition, float itemSize, float boundary, float multiplier) {\n        if (lensPosition < 0) {\n            return itemSize;\n        }\n        Settings settings = new Settings(context);\n        float scaleDifference = settings.getFloat(Settings.KEY_SCALE_FACTOR) - Settings.MIN_SCALE_FACTOR;\n        float d = Settings.MIN_SCALE_FACTOR + scaleDifference * multiplier;\n        if (lensPosition >= itemPosition) {\n            itemPosition = itemPosition - d * (itemSize / 2.0f);\n        } else {\n            itemPosition = itemPosition + d * (itemSize / 2.0f);\n        }\n        return LensCalculator.shiftPoint(context, lensPosition, itemPosition, boundary, multiplier);\n    }\n\n    // Graphical Fisheye Lens algorithm for determining final scaled size\n    public static float calculateSquareScaledSize(float scaledPositionX, float shiftedPositionX, float scaledPositionY, float shiftedPositionY) {\n        return 2.0f * Math.min(Math.abs(scaledPositionX - shiftedPositionX), Math.abs(scaledPositionY - shiftedPositionY));\n    }\n\n    // Algorithm for calculating new rect\n    public static RectF calculateRect(float newCenterX, float newCenterY, float newSize) {\n        RectF newRect = new RectF(\n                newCenterX - newSize / 2.0f,\n                newCenterY - newSize / 2.0f,\n                newCenterX + newSize / 2.0f,\n                newCenterY + newSize / 2.0f);\n        return newRect;\n    }\n\n    // Algorithm for determining if touch point is within rect\n    public static boolean isInsideRect(float x, float y, RectF rect) {\n        if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    // Algorithm for converting dp measurements to pixels\n    public static float convertDpToPixel(float dp, Context context) {\n        Resources resources = context.getResources();\n        DisplayMetrics metrics = resources.getDisplayMetrics();\n        float px = dp * ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);\n        return px;\n    }\n\n    // Algorithm for converting pixels to dp measurements\n    public static float convertPixelsToDp(float px, Context context) {\n        Resources resources = context.getResources();\n        DisplayMetrics metrics = resources.getDisplayMetrics();\n        float dp = px / ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);\n        return dp;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/util/NightModeUtil.java",
    "content": "package nickrout.lenslauncher.util;\n\nimport android.support.v7.app.AppCompatDelegate;\n\n/**\n * Created by nicholasrout on 2017/01/15.\n */\n\npublic class NightModeUtil {\n\n    public static String getNightModeDisplayName(@AppCompatDelegate.NightMode int nightMode) {\n        switch (nightMode) {\n            case AppCompatDelegate.MODE_NIGHT_NO:\n                return \"Light\";\n            case AppCompatDelegate.MODE_NIGHT_YES:\n                return \"Dark\";\n            case AppCompatDelegate.MODE_NIGHT_AUTO:\n                return \"Auto\";\n            default:\n                return \"Follow System\";\n        }\n    }\n\n    public static @AppCompatDelegate.NightMode int getNightModeFromDisplayName(String displayName) {\n        switch (displayName) {\n            case \"Light\":\n                return AppCompatDelegate.MODE_NIGHT_NO;\n            case \"Dark\":\n                return AppCompatDelegate.MODE_NIGHT_YES;\n            case \"Auto\":\n                return AppCompatDelegate.MODE_NIGHT_AUTO;\n            default:\n                return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/nickrout/lenslauncher/util/Settings.java",
    "content": "package nickrout.lenslauncher.util;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.preference.PreferenceManager;\nimport android.support.v7.app.AppCompatDelegate;\n\n/**\n * Created by nicholasrout on 2016/04/02.\n */\npublic class Settings {\n\n    public static final float DEFAULT_ICON_SIZE = 18.0f;\n    public static final float DEFAULT_DISTORTION_FACTOR = 2.5f;\n    public static final float DEFAULT_SCALE_FACTOR = 1.0f;\n    public static final long DEFAULT_ANIMATION_TIME = 200;\n    public static final boolean DEFAULT_VIBRATE_APP_HOVER = false;\n    public static final boolean DEFAULT_VIBRATE_APP_LAUNCH = true;\n    public static final boolean DEFAULT_SHOW_NAME_APP_HOVER = true;\n    public static final boolean DEFAULT_SHOW_TOUCH_SELECTION = false;\n    public static final boolean DEFAULT_SHOW_NEW_APP_TAG = true;\n    public static final String DEFAULT_BACKGROUND = \"Wallpaper\";\n    public static final String DEFAULT_BACKGROUND_COLOR = \"#FFF8BBD0\";\n    public static final String DEFAULT_HIGHLIGHT_COLOR = \"#FFF50057\";\n    public static final String DEFAULT_ICON_PACK_LABEL_NAME = \"Default Icon Pack\";\n    public static final int DEFAULT_SORT_TYPE = 0;\n    public static final int DEFAULT_NIGHT_MODE = AppCompatDelegate.MODE_NIGHT_NO;\n\n    // These values are for the progress bars, their real values = (MAX_VALUE / INTERVAL (eg. 2)) + MIN_VALUE\n    public static final int MAX_ICON_SIZE = 45;\n    public static final int MAX_DISTORTION_FACTOR = 9;\n    public static final int MAX_SCALE_FACTOR = 5;\n    public static final int MAX_ANIMATION_TIME = 600;\n\n    public static final int SHOW_NEW_APP_TAG_DURATION = 12 * 60 * 60 * 1000; /* An app has the new tag for twelve hours. If openCount >= 1, the new tag is not drawn. */\n\n    public static final float MIN_ICON_SIZE = 10.0f;\n    public static final float MIN_DISTORTION_FACTOR = 0.5f;\n    public static final float MIN_SCALE_FACTOR = 1.0f;\n    public static final long MIN_ANIMATION_TIME = 100;\n\n    public static final float DEFAULT_FLOAT = Float.MIN_VALUE;\n    public static final long DEFAULT_LONG = Long.MIN_VALUE;\n    public static final boolean DEFAULT_BOOLEAN = false;\n    public static final String DEFAULT_STRING = \"\";\n\n    public static final String KEY_ICON_SIZE = \"min_icon_size\";\n    public static final String KEY_DISTORTION_FACTOR = \"distortion_factor\";\n    public static final String KEY_SCALE_FACTOR = \"scale_factor\";\n    public static final String KEY_ANIMATION_TIME = \"animation_time\";\n    public static final String KEY_VIBRATE_APP_HOVER = \"vibrate_app_hover\";\n    public static final String KEY_VIBRATE_APP_LAUNCH = \"vibrate_app_launch\";\n    public static final String KEY_SHOW_NAME_APP_HOVER = \"show_name_app_hover\";\n    public static final String KEY_SHOW_TOUCH_SELECTION = \"show_touch_selection\";\n    public static final String KEY_SHOW_NEW_APP_TAG = \"show_new_tag_app\";\n    public static final String KEY_BACKGROUND = \"background\";\n    public static final String KEY_BACKGROUND_COLOR = \"background_color\";\n    public static final String KEY_HIGHLIGHT_COLOR = \"show_touch_selection_color\";\n    public static final String KEY_ICON_PACK_LABEL_NAME = \"icon_pack_label_name\";\n    public static final String KEY_SORT_TYPE = \"sort_type\";\n    public static final String KEY_NIGHT_MODE = \"night_mode\";\n\n    private Context mContext;\n    private SharedPreferences mPrefs;\n\n    public Settings(Context context) {\n        mContext = context;\n    }\n\n    private SharedPreferences sharedPreferences() {\n        if (mPrefs == null) {\n            mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);\n        }\n        return mPrefs;\n    }\n\n    public void save(String name, int value) {\n        sharedPreferences().edit().putInt(name, value).commit();\n    }\n\n    public @AppCompatDelegate.NightMode int getNightMode() {\n        switch (sharedPreferences().getInt(KEY_NIGHT_MODE, DEFAULT_NIGHT_MODE)) {\n            case AppCompatDelegate.MODE_NIGHT_AUTO:\n                return AppCompatDelegate.MODE_NIGHT_AUTO;\n            case AppCompatDelegate.MODE_NIGHT_NO:\n                return AppCompatDelegate.MODE_NIGHT_NO;\n            case AppCompatDelegate.MODE_NIGHT_YES:\n                return AppCompatDelegate.MODE_NIGHT_YES;\n            default:\n                return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;\n        }\n    }\n\n    public void save(String name, float value) {\n        sharedPreferences().edit().putFloat(name, value).commit();\n    }\n\n    public float getFloat(String name) {\n        if (name.equals(KEY_ICON_SIZE)) {\n            if (sharedPreferences().getFloat(name, DEFAULT_ICON_SIZE) < MIN_ICON_SIZE) {\n                save(name, MIN_ICON_SIZE);\n            } else if (sharedPreferences().getFloat(name, DEFAULT_ICON_SIZE) > getMaxFloatValue(name)) {\n                save(name, getMaxFloatValue(name));\n            }\n            return sharedPreferences().getFloat(name, DEFAULT_ICON_SIZE);\n        } else if (name.equals(KEY_DISTORTION_FACTOR)) {\n            if (sharedPreferences().getFloat(name, DEFAULT_DISTORTION_FACTOR) < MIN_DISTORTION_FACTOR) {\n                save(name, MIN_DISTORTION_FACTOR);\n            } else if (sharedPreferences().getFloat(name, DEFAULT_DISTORTION_FACTOR) > getMaxFloatValue(name)) {\n                save(name, getMaxFloatValue(name));\n            }\n            return sharedPreferences().getFloat(name, DEFAULT_DISTORTION_FACTOR);\n        } else if (name.equals(KEY_SCALE_FACTOR)) {\n            if (sharedPreferences().getFloat(name, DEFAULT_SCALE_FACTOR) < MIN_SCALE_FACTOR) {\n                save(name, MIN_SCALE_FACTOR);\n            } else if (sharedPreferences().getFloat(name, DEFAULT_SCALE_FACTOR) > getMaxFloatValue(name)) {\n                save(name, getMaxFloatValue(name));\n            }\n            return sharedPreferences().getFloat(name, DEFAULT_SCALE_FACTOR);\n        } else {\n            return sharedPreferences().getFloat(name, DEFAULT_FLOAT);\n        }\n    }\n\n    public void save(String name, long value) {\n        sharedPreferences().edit().putLong(name, value).commit();\n    }\n\n    public long getLong(String name) {\n        if (name.equals(KEY_ANIMATION_TIME)) {\n            if (sharedPreferences().getLong(name, DEFAULT_ANIMATION_TIME) < MIN_ANIMATION_TIME) {\n                save(name, MIN_ANIMATION_TIME);\n            } else if (sharedPreferences().getLong(name, DEFAULT_ANIMATION_TIME) > getMaxLongValue(name)) {\n                save(name, getMaxLongValue(name));\n            }\n            return sharedPreferences().getLong(name, DEFAULT_ANIMATION_TIME);\n        } else {\n            return sharedPreferences().getLong(name, DEFAULT_LONG);\n        }\n    }\n\n    public void save(String name, String value) {\n        sharedPreferences().edit().putString(name, value).commit();\n    }\n\n    public String getString(String name) {\n        if (name.equals(KEY_BACKGROUND)) {\n            return sharedPreferences().getString(name, DEFAULT_BACKGROUND);\n        } else if (name.equals(KEY_BACKGROUND_COLOR)) {\n            return sharedPreferences().getString(name, DEFAULT_BACKGROUND_COLOR);\n        } else if (name.equals(KEY_HIGHLIGHT_COLOR)) {\n            return sharedPreferences().getString(name, DEFAULT_HIGHLIGHT_COLOR);\n        } else if (name.equals(KEY_ICON_PACK_LABEL_NAME)) {\n            return sharedPreferences().getString(name, DEFAULT_ICON_PACK_LABEL_NAME);\n        } else {\n            return sharedPreferences().getString(name, DEFAULT_STRING);\n        }\n    }\n\n\n    public void save(String name, boolean value) {\n        sharedPreferences().edit().putBoolean(name, value).commit();\n    }\n\n    public boolean getBoolean(String name) {\n        if (name.equals(KEY_VIBRATE_APP_HOVER)) {\n            return sharedPreferences().getBoolean(name, DEFAULT_VIBRATE_APP_HOVER);\n        } else if (name.equals(KEY_VIBRATE_APP_LAUNCH)) {\n            return sharedPreferences().getBoolean(name, DEFAULT_VIBRATE_APP_LAUNCH);\n        } else if (name.equals(KEY_SHOW_NAME_APP_HOVER)) {\n            return sharedPreferences().getBoolean(name, DEFAULT_SHOW_NAME_APP_HOVER);\n        } else if (name.equals(KEY_SHOW_TOUCH_SELECTION)) {\n            return sharedPreferences().getBoolean(name, DEFAULT_SHOW_TOUCH_SELECTION);\n        } else if (name.equals(KEY_SHOW_NEW_APP_TAG)) {\n            return sharedPreferences().getBoolean(name, DEFAULT_SHOW_NEW_APP_TAG);\n        } else {\n            return sharedPreferences().getBoolean(name, DEFAULT_BOOLEAN);\n        }\n    }\n\n    public void save(AppSorter.SortType value) {\n        save(KEY_SORT_TYPE, value.ordinal());\n    }\n\n    public AppSorter.SortType getSortType() {\n        int ordinal = sharedPreferences().getInt(KEY_SORT_TYPE, DEFAULT_SORT_TYPE);\n        return AppSorter.SortType.values()[ordinal];\n    }\n\n    public float getMaxFloatValue(String name) {\n        if (name.equals(KEY_ICON_SIZE)) {\n            return (float) MAX_ICON_SIZE + MIN_ICON_SIZE;\n        } else if (name.equals(KEY_DISTORTION_FACTOR)) {\n            return (float) MAX_DISTORTION_FACTOR / 2 + MIN_DISTORTION_FACTOR;\n        } else if (name.equals(KEY_SCALE_FACTOR)) {\n            return (float) MAX_SCALE_FACTOR / 2 + MIN_SCALE_FACTOR;\n        } else {\n            return DEFAULT_FLOAT;\n        }\n    }\n\n    public long getMaxLongValue(String name) {\n        if (name.equals(KEY_ANIMATION_TIME)) {\n            return (long) MAX_ANIMATION_TIME / 2 + MIN_ANIMATION_TIME;\n        } else {\n            return DEFAULT_LONG;\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/res/anim/fade_in.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<alpha\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:interpolator=\"@android:anim/decelerate_interpolator\"\n    android:fromAlpha=\"0.0\"\n    android:toAlpha=\"1.0\"\n    android:duration=\"@android:integer/config_mediumAnimTime\" />"
  },
  {
    "path": "app/src/main/res/anim/fade_out.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<alpha\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:interpolator=\"@android:anim/decelerate_interpolator\"\n    android:fromAlpha=\"1.0\"\n    android:toAlpha=\"0.0\"\n    android:duration=\"@android:integer/config_mediumAnimTime\" />"
  },
  {
    "path": "app/src/main/res/anim/slide_in_left.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:duration=\"@android:integer/config_shortAnimTime\">\n    <translate\n        android:fromXDelta=\"100%p\"\n        android:toXDelta=\"0\" />\n</set>"
  },
  {
    "path": "app/src/main/res/anim/slide_in_right.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:duration=\"@android:integer/config_shortAnimTime\" >\n    <translate\n        android:fromXDelta=\"-100%p\"\n        android:toXDelta=\"0\" />\n</set>"
  },
  {
    "path": "app/src/main/res/anim/slide_out_left.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:duration=\"@android:integer/config_shortAnimTime\">\n    <translate\n        android:fromXDelta=\"0\"\n        android:toXDelta=\"100%p\" />\n</set>"
  },
  {
    "path": "app/src/main/res/anim/slide_out_right.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:duration=\"@android:integer/config_shortAnimTime\">\n    <translate\n        android:fromXDelta=\"0\"\n        android:toXDelta=\"-100%p\" />\n</set>"
  },
  {
    "path": "app/src/main/res/animator/raise.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item\n        android:state_enabled=\"true\"\n        android:state_pressed=\"true\">\n        <objectAnimator\n            android:duration=\"@android:integer/config_shortAnimTime\"\n            android:propertyName=\"translationZ\"\n            android:valueTo=\"4dp\" />\n    </item>\n    <item>\n        <objectAnimator\n            android:duration=\"@android:integer/config_shortAnimTime\"\n            android:propertyName=\"translationZ\"\n            android:valueTo=\"0dp\" />\n    </item>\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n    <size\n        android:width=\"108dp\"\n        android:height=\"108dp\"/>\n    <solid\n        android:color=\"@color/colorPrimary\"/>\n</shape>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"108dp\"\n        android:height=\"108dp\"\n        android:viewportWidth=\"108.0\"\n        android:viewportHeight=\"108.0\">\n    <path\n        android:pathData=\"M54.5,35C55.34,35 56,34.34 56,33.5C56,32.66 55.34,32 54.5,32C53.66,32 53,32.66 53,33.5C53,34.34 53.66,35 54.5,35ZM54.5,74C53.66,74 53,74.66 53,75.5C53,76.34 53.66,77 54.5,77C55.34,77 56,76.34 56,75.5C56,74.66 55.34,74 54.5,74ZM75.5,53C74.66,53 74,53.66 74,54.5C74,55.34 74.66,56 75.5,56C76.34,56 77,55.34 77,54.5C77,53.66 76.34,53 75.5,53ZM33.5,53C32.66,53 32,53.66 32,54.5C32,55.34 32.66,56 33.5,56C34.34,56 35,55.34 35,54.5C35,53.66 34.34,53 33.5,53ZM42.5,51.5C40.85,51.5 39.5,52.85 39.5,54.5C39.5,56.15 40.85,57.5 42.5,57.5C44.15,57.5 45.5,56.15 45.5,54.5C45.5,52.85 44.15,51.5 42.5,51.5ZM42.5,39.5C40.85,39.5 39.5,40.85 39.5,42.5C39.5,44.15 40.85,45.5 42.5,45.5C44.15,45.5 45.5,44.15 45.5,42.5C45.5,40.85 44.15,39.5 42.5,39.5ZM66.5,51.5C64.85,51.5 63.5,52.85 63.5,54.5C63.5,56.15 64.85,57.5 66.5,57.5C68.15,57.5 69.5,56.15 69.5,54.5C69.5,52.85 68.15,51.5 66.5,51.5ZM66.5,63.5C64.85,63.5 63.5,64.85 63.5,66.5C63.5,68.15 64.85,69.5 66.5,69.5C68.15,69.5 69.5,68.15 69.5,66.5C69.5,64.85 68.15,63.5 66.5,63.5ZM66.5,39.5C64.85,39.5 63.5,40.85 63.5,42.5C63.5,44.15 64.85,45.5 66.5,45.5C68.15,45.5 69.5,44.15 69.5,42.5C69.5,40.85 68.15,39.5 66.5,39.5ZM54.5,39.5C52.85,39.5 51.5,40.85 51.5,42.5C51.5,44.15 52.85,45.5 54.5,45.5C56.15,45.5 57.5,44.15 57.5,42.5C57.5,40.85 56.15,39.5 54.5,39.5ZM54.5,63.5C52.85,63.5 51.5,64.85 51.5,66.5C51.5,68.15 52.85,69.5 54.5,69.5C56.15,69.5 57.5,68.15 57.5,66.5C57.5,64.85 56.15,63.5 54.5,63.5ZM42.5,63.5C40.85,63.5 39.5,64.85 39.5,66.5C39.5,68.15 40.85,69.5 42.5,69.5C44.15,69.5 45.5,68.15 45.5,66.5C45.5,64.85 44.15,63.5 42.5,63.5ZM54.5,50C52.01,50 50,52.01 50,54.5C50,56.99 52.01,59 54.5,59C56.99,59 59,56.99 59,54.5C59,52.01 56.99,50 54.5,50Z\"\n        android:fillType=\"evenOdd\"\n        android:fillColor=\"#FFFFFF\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_about.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.design.widget.CoordinatorLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".ui.AboutActivity\">\n\n    <android.support.design.widget.AppBarLayout\n        android:layout_height=\"wrap_content\"\n        android:layout_width=\"match_parent\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <android.support.design.widget.CollapsingToolbarLayout\n            android:id=\"@+id/collapsing_toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            app:layout_scrollFlags=\"scroll|exitUntilCollapsed\"\n            app:contentScrim=\"?attr/colorPrimary\"\n            app:expandedTitleMarginStart=\"24dp\"\n            app:expandedTitleMarginEnd=\"64dp\">\n\n            <ImageView\n                android:id=\"@+id/backdrop\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:scaleType=\"centerCrop\"\n                app:layout_collapseMode=\"parallax\"\n                android:src=\"@drawable/im_about\"\n                tools:ignore=\"contentDescription\" />\n\n            <android.support.v7.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?attr/actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"\n                app:layout_collapseMode=\"pin\" />\n\n        </android.support.design.widget.CollapsingToolbarLayout>\n\n    </android.support.design.widget.AppBarLayout>\n\n    <android.support.v4.widget.NestedScrollView\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:clipToPadding=\"false\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <TextView\n            android:id=\"@+id/text_view_about\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center\"\n            android:textColorHighlight=\"@color/colorPrimary\"\n            android:textColorLink=\"@color/colorAccent\"\n            android:padding=\"@dimen/padding_about\"/>\n\n    </android.support.v4.widget.NestedScrollView>\n\n</android.support.design.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_fake_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"nickrout.lenslauncher.ui.FakeLauncherActivity\">\n</RelativeLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_home.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <nickrout.lenslauncher.ui.LensView\n        android:id=\"@+id/lens_view_apps\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:hapticFeedbackEnabled=\"true\"\n        android:visibility=\"invisible\"/>\n\n    <me.zhanghai.android.materialprogressbar.MaterialProgressBar\n        android:id=\"@+id/progress_home\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"/>\n\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_settings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.design.widget.CoordinatorLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/main_content\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <android.support.design.widget.AppBarLayout\n        android:id=\"@+id/appbar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <android.support.v7.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?attr/actionBarSize\"\n            android:background=\"?attr/colorPrimary\"\n            app:layout_scrollFlags=\"scroll|enterAlways\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n\n        <android.support.design.widget.TabLayout\n            android:id=\"@+id/tabs\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?attr/actionBarSize\"\n            android:layout_gravity=\"bottom\"\n            app:tabMode=\"fixed\"/>\n\n    </android.support.design.widget.AppBarLayout>\n\n    <android.support.v4.view.ViewPager\n        android:id=\"@+id/viewpager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\" />\n\n    <android.support.design.widget.FloatingActionButton\n        android:id=\"@+id/fab_sort\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"@dimen/margin_fab\"\n        android:layout_gravity=\"bottom|end\"\n        android:src=\"@drawable/ic_sort_white_24dp\"\n        app:fabSize=\"normal\" />\n\n</android.support.design.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_apps.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <android.support.v7.widget.RecyclerView\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:id=\"@+id/recycler_apps\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:paddingTop=\"@dimen/activity_vertical_margin\"\n        android:paddingBottom=\"80dp\"\n        android:paddingStart=\"@dimen/activity_horizontal_margin_apps\"\n        android:paddingLeft=\"@dimen/activity_horizontal_margin_apps\"\n        android:paddingEnd=\"@dimen/activity_horizontal_margin_apps\"\n        android:paddingRight=\"@dimen/activity_horizontal_margin_apps\"\n        android:clipToPadding=\"false\"\n        android:visibility=\"invisible\"/>\n\n    <me.zhanghai.android.materialprogressbar.MaterialProgressBar\n        android:id=\"@+id/progress_apps\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"/>\n\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_lens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v4.widget.NestedScrollView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\" >\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <nickrout.lenslauncher.ui.LensView\n            android:id=\"@+id/lens_view_settings\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/height_lens_preview\" />\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:background=\"@color/colorDivider\" />\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginTop=\"@dimen/activity_vertical_margin\"\n            android:layout_marginBottom=\"@dimen/activity_vertical_margin\"\n            android:layout_marginStart=\"@dimen/activity_horizontal_margin\"\n            android:layout_marginEnd=\"@dimen/activity_horizontal_margin\"\n            android:orientation=\"vertical\">\n\n            <RelativeLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_margin=\"8dp\">\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentStart=\"true\"\n                    android:layout_alignParentLeft=\"true\"\n                    android:text=\"@string/setting_min_icon_size\" />\n\n                <TextView\n                    android:id=\"@+id/value_min_icon_size\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentEnd=\"true\"\n                    android:layout_alignParentRight=\"true\"\n                    android:textStyle=\"bold\" />\n\n            </RelativeLayout>\n\n            <android.support.v7.widget.AppCompatSeekBar\n                android:id=\"@+id/seek_bar_min_icon_size\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginBottom=\"16dp\" />\n\n            <RelativeLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_margin=\"8dp\">\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentStart=\"true\"\n                    android:layout_alignParentLeft=\"true\"\n                    android:text=\"@string/setting_distortion_factor\" />\n\n                <TextView\n                    android:id=\"@+id/value_distortion_factor\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentEnd=\"true\"\n                    android:layout_alignParentRight=\"true\"\n                    android:textStyle=\"bold\" />\n\n            </RelativeLayout>\n\n            <android.support.v7.widget.AppCompatSeekBar\n                android:id=\"@+id/seek_bar_distortion_factor\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginBottom=\"16dp\" />\n\n            <RelativeLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_margin=\"8dp\">\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentStart=\"true\"\n                    android:layout_alignParentLeft=\"true\"\n                    android:text=\"@string/setting_scale_factor\" />\n\n                <TextView\n                    android:id=\"@+id/value_scale_factor\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentEnd=\"true\"\n                    android:layout_alignParentRight=\"true\"\n                    android:textStyle=\"bold\" />\n\n            </RelativeLayout>\n\n            <android.support.v7.widget.AppCompatSeekBar\n                android:id=\"@+id/seek_bar_scale_factor\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginBottom=\"16dp\" />\n\n            <RelativeLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_margin=\"8dp\">\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentStart=\"true\"\n                    android:layout_alignParentLeft=\"true\"\n                    android:text=\"@string/setting_animation_time\" />\n\n                <TextView\n                    android:id=\"@+id/value_animation_time\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentEnd=\"true\"\n                    android:layout_alignParentRight=\"true\"\n                    android:textStyle=\"bold\" />\n\n            </RelativeLayout>\n\n            <android.support.v7.widget.AppCompatSeekBar\n                android:id=\"@+id/seek_bar_animation_time\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginBottom=\"16dp\" />\n\n        </LinearLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:background=\"@color/colorDivider\" />\n\n    </LinearLayout>\n\n</android.support.v4.widget.NestedScrollView>"
  },
  {
    "path": "app/src/main/res/layout/fragment_settings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v4.widget.NestedScrollView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <LinearLayout\n            android:id=\"@+id/layout_home_launcher\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"?android:attr/selectableItemBackground\"\n            android:orientation=\"vertical\"\n            android:paddingBottom=\"@dimen/activity_vertical_margin\"\n            android:paddingStart=\"@dimen/activity_horizontal_margin\"\n            android:paddingEnd=\"@dimen/activity_horizontal_margin\"\n            android:paddingTop=\"@dimen/activity_vertical_margin\" >\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"@string/setting_home_launcher\"\n                android:textStyle=\"bold\" />\n\n            <TextView\n                android:id=\"@+id/text_view_selected_home_launcher\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"/>\n\n        </LinearLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:background=\"@color/colorDivider\" />\n\n        <LinearLayout\n            android:id=\"@+id/layout_icon_pack\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"horizontal\"\n            android:baselineAligned=\"false\"\n            android:background=\"?android:attr/selectableItemBackground\">\n\n            <LinearLayout\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:orientation=\"vertical\"\n                android:paddingBottom=\"@dimen/activity_vertical_margin\"\n                android:paddingStart=\"@dimen/activity_horizontal_margin\"\n                android:paddingEnd=\"@dimen/activity_horizontal_margin\"\n                android:paddingTop=\"@dimen/activity_vertical_margin\" >\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"@string/setting_icon_pack\"\n                    android:textStyle=\"bold\" />\n\n                <TextView\n                    android:id=\"@+id/text_view_selected_icon_pack\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"@string/setting_default_icon_pack\" />\n    \n            </LinearLayout>\n\n        </LinearLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:background=\"@color/colorDivider\" />\n\n        <LinearLayout\n            android:id=\"@+id/layout_night_mode\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"horizontal\"\n            android:baselineAligned=\"false\"\n            android:background=\"?android:attr/selectableItemBackground\">\n            \n            <LinearLayout\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:orientation=\"vertical\"\n                android:paddingBottom=\"@dimen/activity_vertical_margin\"\n                android:paddingStart=\"@dimen/activity_horizontal_margin\"\n                android:paddingEnd=\"@dimen/activity_horizontal_margin\"\n                android:paddingTop=\"@dimen/activity_vertical_margin\" >\n    \n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"@string/setting_night_mode\"\n                    android:textStyle=\"bold\" />\n    \n                <TextView\n                    android:id=\"@+id/text_view_selected_night_mode\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"/>\n    \n            </LinearLayout>\n            \n        </LinearLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:background=\"@color/colorDivider\" />\n\n        <LinearLayout\n            android:id=\"@+id/layout_background\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"horizontal\"\n            android:baselineAligned=\"false\"\n            android:background=\"?android:attr/selectableItemBackground\">\n            \n            <RelativeLayout\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:paddingBottom=\"@dimen/activity_vertical_margin\"\n                android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                android:paddingRight=\"@dimen/activity_horizontal_margin\"\n                android:paddingTop=\"@dimen/activity_vertical_margin\">\n    \n                <LinearLayout\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:orientation=\"vertical\"\n                    android:layout_alignParentStart=\"true\"\n                    android:layout_alignParentLeft=\"true\"\n                    android:layout_centerVertical=\"true\">\n    \n                    <TextView\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\"\n                        android:text=\"@string/setting_background\"\n                        android:textStyle=\"bold\" />\n    \n                    <TextView\n                        android:id=\"@+id/text_view_selected_background\"\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\"\n                        tools:text=\"#FFFFFF\" />\n    \n                </LinearLayout>\n    \n                <ImageView\n                    android:id=\"@+id/image_view_selected_background_color\"\n                    android:layout_width=\"@dimen/diameter_highlight_color_switch\"\n                    android:layout_height=\"@dimen/diameter_highlight_color_switch\"\n                    android:layout_alignParentEnd=\"true\"\n                    android:layout_alignParentRight=\"true\"\n                    android:layout_centerVertical=\"true\"\n                    tools:ignore=\"contentDescription\" />\n    \n            </RelativeLayout>\n                \n        </LinearLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:background=\"@color/colorDivider\" />\n\n        <LinearLayout\n            android:id=\"@+id/layout_highlight_color\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"horizontal\"\n            android:baselineAligned=\"false\"\n            android:background=\"?android:attr/selectableItemBackground\">\n            \n            <RelativeLayout\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:paddingBottom=\"@dimen/activity_vertical_margin\"\n                android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                android:paddingRight=\"@dimen/activity_horizontal_margin\"\n                android:paddingTop=\"@dimen/activity_vertical_margin\">\n    \n                <LinearLayout\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:orientation=\"vertical\"\n                    android:layout_alignParentStart=\"true\"\n                    android:layout_alignParentLeft=\"true\"\n                    android:layout_centerVertical=\"true\">\n    \n                    <TextView\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\"\n                        android:text=\"@string/setting_highlight_color\"\n                        android:textStyle=\"bold\" />\n    \n                    <TextView\n                        android:id=\"@+id/text_view_selected_highlight_color\"\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\"\n                        tools:text=\"#FFFFFF\" />\n    \n                </LinearLayout>\n    \n                <ImageView\n                    android:id=\"@+id/image_view_selected_highlight_color\"\n                    android:layout_width=\"@dimen/diameter_highlight_color_switch\"\n                    android:layout_height=\"@dimen/diameter_highlight_color_switch\"\n                    android:layout_alignParentEnd=\"true\"\n                    android:layout_alignParentRight=\"true\"\n                    android:layout_centerVertical=\"true\"\n                    tools:ignore=\"contentDescription\" />\n    \n            </RelativeLayout>\n            \n        </LinearLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:background=\"@color/colorDivider\" />\n\n        <android.support.v7.widget.SwitchCompat\n            android:id=\"@+id/switch_vibrate_app_hover\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:paddingTop=\"@dimen/activity_vertical_margin\"\n            android:paddingBottom=\"@dimen/activity_vertical_margin\"\n            android:paddingStart=\"@dimen/activity_horizontal_margin\"\n            android:paddingEnd=\"@dimen/activity_horizontal_margin\"\n            android:text=\"@string/setting_vibrate_app_hover\"\n            android:textColor=\"?android:attr/textColorSecondary\"/>\n\n        <android.support.v7.widget.SwitchCompat\n            android:id=\"@+id/switch_vibrate_app_launch\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:paddingTop=\"@dimen/activity_vertical_margin\"\n            android:paddingBottom=\"@dimen/activity_vertical_margin\"\n            android:paddingStart=\"@dimen/activity_horizontal_margin\"\n            android:paddingEnd=\"@dimen/activity_horizontal_margin\"\n            android:text=\"@string/setting_vibrate_app_launch\"\n            android:textColor=\"?android:attr/textColorSecondary\"/>\n\n        <android.support.v7.widget.SwitchCompat\n            android:id=\"@+id/switch_show_name_app_hover\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:paddingTop=\"@dimen/activity_vertical_margin\"\n            android:paddingBottom=\"@dimen/activity_vertical_margin\"\n            android:paddingStart=\"@dimen/activity_horizontal_margin\"\n            android:paddingEnd=\"@dimen/activity_horizontal_margin\"\n            android:text=\"@string/setting_show_name_app_hover\"\n            android:textColor=\"?android:attr/textColorSecondary\"/>\n\n        <android.support.v7.widget.SwitchCompat\n            android:id=\"@+id/switch_show_new_app_tag\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:paddingTop=\"@dimen/activity_vertical_margin\"\n            android:paddingBottom=\"@dimen/activity_vertical_margin\"\n            android:paddingStart=\"@dimen/activity_horizontal_margin\"\n            android:paddingEnd=\"@dimen/activity_horizontal_margin\"\n            android:text=\"@string/setting_show_new_app_tag\"\n            android:textColor=\"?android:attr/textColorSecondary\"/>\n\n        <android.support.v7.widget.SwitchCompat\n            android:id=\"@+id/switch_show_touch_selection\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:paddingTop=\"@dimen/activity_vertical_margin\"\n            android:paddingBottom=\"@dimen/activity_vertical_margin\"\n            android:paddingStart=\"@dimen/activity_horizontal_margin\"\n            android:paddingEnd=\"@dimen/activity_horizontal_margin\"\n            android:text=\"@string/setting_show_touch_selection\"\n            android:textColor=\"?android:attr/textColorSecondary\"/>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:background=\"@color/colorDivider\" />\n\n    </LinearLayout>\n\n</android.support.v4.widget.NestedScrollView>"
  },
  {
    "path": "app/src/main/res/layout/layout_pro.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:gravity=\"center\">\n\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:padding=\"8dp\"\n        android:text=\"@string/pro\"\n        android:textStyle=\"bold\"\n        android:textColor=\"@color/colorWhite\"\n        android:background=\"?attr/colorAccent\" />\n\n</RelativeLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/recycler_item_app.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v7.widget.CardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/element_app_container\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"@dimen/margin_app\"\n    android:layout_marginStart=\"@dimen/margin_app\"\n    android:layout_marginLeft=\"@dimen/margin_app\"\n    android:layout_marginEnd=\"@dimen/margin_app\"\n    android:layout_marginRight=\"@dimen/margin_app\"\n    card_view:cardCornerRadius=\"@dimen/radius_corner_card\"\n    android:foreground=\"?attr/selectableItemBackground\"\n    android:stateListAnimator=\"@animator/raise\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <ImageView\n            android:id=\"@+id/element_app_icon\"\n            android:layout_width=\"@dimen/width_app_icon\"\n            android:layout_height=\"@dimen/width_app_icon\"\n            android:layout_margin=\"8dp\"\n            tools:ignore=\"contentDescription\"/>\n\n        <TextView\n            android:id=\"@+id/element_app_label\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerVertical=\"true\"\n            android:layout_marginStart=\"16dp\"\n            android:layout_marginLeft=\"16dp\"\n            android:layout_toEndOf=\"@+id/element_app_icon\"\n            android:layout_toRightOf=\"@+id/element_app_icon\"\n            android:layout_toStartOf=\"@+id/element_app_hide\"\n            android:layout_toLeftOf=\"@+id/element_app_hide\"\n            android:maxLines=\"1\"\n            android:ellipsize=\"end\"\n            tools:text=\"AppName\"\n            android:textStyle=\"bold\" />\n\n        <ImageView\n            android:id=\"@+id/element_app_hide\"\n            android:layout_width=\"@dimen/width_app_icon\"\n            android:layout_height=\"@dimen/height_app_action_button\"\n            android:scaleType=\"centerInside\"\n            android:layout_toStartOf=\"@+id/element_app_menu\"\n            android:layout_toLeftOf=\"@+id/element_app_menu\"\n            android:src=\"@drawable/ic_visibility_grey_24dp\"\n            android:background=\"?attr/selectableItemBackgroundBorderless\"\n            tools:ignore=\"contentDescription\"\n            android:tint=\"@color/colorAppTint\"/>\n\n        <ImageView\n            android:id=\"@+id/element_app_menu\"\n            android:layout_width=\"@dimen/width_app_icon\"\n            android:layout_height=\"@dimen/height_app_action_button\"\n            android:scaleType=\"centerInside\"\n            android:layout_alignParentEnd=\"true\"\n            android:layout_alignParentRight=\"true\"\n            android:src=\"@drawable/ic_more_vert_grey_24dp\"\n            android:background=\"?attr/selectableItemBackgroundBorderless\"\n            tools:ignore=\"contentDescription\"\n            android:tint=\"@color/colorAppTint\"/>\n\n    </RelativeLayout>\n\n</android.support.v7.widget.CardView>"
  },
  {
    "path": "app/src/main/res/menu/menu_app.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item\n        android:id=\"@+id/menu_item_element_app_info\"\n        android:title=\"@string/menu_app_info\"\n        android:visible=\"true\" />\n\n    <item\n        android:id=\"@+id/menu_item_element_uninstall\"\n        android:title=\"@string/menu_app_uninstall\"\n        android:visible=\"true\" />\n\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_settings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/menu_item_about\"\n        android:title=\"@string/menu_title_about\"\n        app:showAsAction=\"never\">\n    </item>\n\n    <item\n        android:id=\"@+id/menu_item_reset_default_settings\"\n        android:title=\"@string/menu_title_reset_defaults\"\n        app:showAsAction=\"never\">\n    </item>\n\n    <item\n        android:id=\"@+id/menu_item_show_apps\"\n        android:icon=\"@drawable/ic_apps_white_24dp\"\n        android:title=\"@string/menu_title_show_apps\"\n        app:showAsAction=\"ifRoom\">\n    </item>\n\n</menu>"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon\n    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\"/>\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\"/>\n</adaptive-icon>\n"
  },
  {
    "path": "app/src/main/res/values/arrays.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <array name=\"icon_pack_launchers\">\n        <item>com.gau.go.launcherex.theme</item>\n        <item>org.adw.launcher.THEMES</item>\n    </array>\n\n    <array name=\"backgrounds\">\n        <item>Wallpaper</item>\n        <item>Color</item>\n    </array>\n\n    <array name=\"night_modes\">\n        <item>Light</item>\n        <item>Dark</item>\n        <item>Auto</item>\n        <item>Follow System</item>\n    </array>\n\n</resources>"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <!-- App Colors -->\n    <color name=\"colorPrimary\">#111111</color>\n    <color name=\"colorPrimaryDark\">#000000</color>\n    <color name=\"colorAccent\">#F50057</color>\n\n    <!-- View Colors -->\n    <color name=\"colorBlack\">#000000</color>\n    <color name=\"colorWhite\">#FFFFFF</color>\n    <color name=\"colorTransparent\">#00FFFFFF</color>\n    <color name=\"colorDivider\">#DDDDDD</color>\n    <color name=\"colorValue\">@color/colorBlack</color>\n    <color name=\"colorShadow\">#80000000</color>\n    <color name=\"colorCircles\">@color/colorBlack</color>\n    <color name=\"colorAppTint\">@color/colorBlack</color>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/dimen.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE resources [\n    <!ELEMENT resources (dimen)*>\n    <!ELEMENT dimen (#PCDATA)>\n    <!ATTLIST dimen\n        name CDATA #REQUIRED>\n    ]>\n<resources>\n\n    <!-- Lens Dimensions -->\n    <dimen name=\"radius_touch_selection\">50dp</dimen>\n    <dimen name=\"stroke_width_touch_selection\">3dp</dimen>\n    <dimen name=\"text_size_lens\">14sp</dimen>\n    <dimen name=\"text_stroke_lens\">1dp</dimen>\n    <dimen name=\"margin_lens_text\">8dp</dimen>\n    <dimen name=\"shadow_text\">1dp</dimen>\n    <dimen name=\"offset_system_vertical\">80dp</dimen>\n    <dimen name=\"offset_system_horizontal\">0dp</dimen>\n    <dimen name=\"radius_new_app_tag\">3dp</dimen>\n    <dimen name=\"margin_new_app_tag\">6dp</dimen>\n    <dimen name=\"height_lens_preview\">360dp</dimen>\n\n    <!-- Settings Dimensions -->\n    <dimen name=\"diameter_highlight_color_switch\">32dp</dimen>\n    <dimen name=\"radius_highlight_color_switch\">16dp</dimen>\n\n    <!-- About Dimensions -->\n    <dimen name=\"text_size_about\">32sp</dimen>\n    <dimen name=\"padding_about\">32dp</dimen>\n    <dimen name=\"header_margin_about\">16dp</dimen>\n\n    <!-- App Recycler Item Dimensions -->\n    <dimen name=\"width_app_icon\">48dp</dimen>\n    <dimen name=\"height_app_action_button\">64dp</dimen>\n    <dimen name=\"radius_corner_card\">4dp</dimen>\n    <dimen name=\"margin_app\">8dp</dimen>\n\n    <!-- General -->\n    <dimen name=\"margin_fab\">16dp</dimen>\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_horizontal_margin_apps\">8dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n\n</resources>"
  },
  {
    "path": "app/src/main/res/values/integers.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <integer name=\"columns_apps\">1</integer>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources>\n\n    <!-- App & Activity Strings -->\n    <string name=\"app_name\">Lens Launcher</string>\n    <string name=\"activity_title_about\">About</string>\n    <string name=\"activity_title_arranger\">Order &amp; Visibility</string>\n    <string name=\"activity_title_settings\">Settings</string>\n    <string name=\"activity_title_apps\">Apps</string>\n\n    <!-- Tab Strings -->\n    <string name=\"tab_lens\">Lens</string>\n    <string name=\"tab_apps\">Apps</string>\n    <string name=\"tab_settings\">Settings</string>\n\n    <!-- Settings Strings -->\n    <string name=\"setting_lens_diameter\">Lens Diameter</string>\n    <string name=\"setting_min_icon_size\">Icon Size</string>\n    <string name=\"setting_distortion_factor\">Distortion Factor</string>\n    <string name=\"setting_scale_factor\">Scale Factor</string>\n    <string name=\"setting_animation_time\">Animation Time</string>\n    <string name=\"setting_vibrate_app_hover\">Vibrate on App Hover</string>\n    <string name=\"setting_vibrate_app_launch\">Vibrate on App Launch</string>\n    <string name=\"setting_show_name_app_hover\">Show Name on App Hover</string>\n    <string name=\"setting_show_touch_selection\">Show Touch Selection</string>\n    <string name=\"setting_show_new_app_tag\">Show New App Tag</string>\n    <string name=\"setting_background_color\">Background Color</string>\n    <string name=\"setting_highlight_color\">Highlight Color</string>\n    <string name=\"setting_icon_pack\">Icon Pack</string>\n    <string name=\"setting_home_launcher\">Home Launcher</string>\n    <string name=\"setting_night_mode\">Night Mode Theme</string>\n    <string name=\"setting_background\">Background</string>\n    <string name=\"setting_default_icon_pack\">Default Icon Pack</string>\n    <string name=\"setting_default_sort_selected\">@string/setting_sort_type_label_ascending</string>\n    <string name=\"setting_sort_type_label_ascending\">App Name (Ascending)</string>\n    <string name=\"setting_sort_type_label_descending\">App Name (Descending)</string>\n    <string name=\"setting_sort_type_install_date_ascending\">Newest First</string>\n    <string name=\"setting_sort_type_install_date_descending\">Oldest First</string>\n    <string name=\"setting_sort_type_open_count_ascending\">Most Opened</string>\n    <string name=\"setting_sort_type_open_count_descending\">Least Opened</string>\n    <string name=\"setting_sort_type_icon_color_ascending\">Icon Color (Light to Dark)</string>\n    <string name=\"setting_sort_type_icon_color_descending\">Icon Color (Dark to Light)</string>\n    <string name=\"setting_app_arranger\">@string/activity_title_arranger</string>\n    <string name=\"setting_sort_apps\">App Order</string>\n\n    <!-- Menu Strings -->\n    <string name=\"menu_title_about\">About</string>\n    <string name=\"menu_title_reset_defaults\">Reset Default Settings</string>\n    <string name=\"menu_title_change_home_launcher\">Change Home Launcher</string>\n    <string name=\"menu_title_show_apps\">Show Apps</string>\n    <string name=\"menu_app_open\"><b>Open</b></string>\n    <string name=\"menu_app_info\">App Info</string>\n    <string name=\"menu_app_uninstall\">Uninstall</string>\n\n    <!-- Error Strings -->\n    <string name=\"error_app_not_found\">App Not Found</string>\n    <string name=\"error_too_many_apps\">Failed to Load Apps</string>\n\n    <!-- Progress Strings -->\n    <string name=\"progress_loading_apps\">Loading Apps</string>\n    <string name=\"progress_loading_icons\">Loading Icons</string>\n\n    <!-- Feedback Strings -->\n    <string name=\"snackbar_reset_successful\">Values Reset To Default</string>\n\n    <!-- About Strings -->\n    <string name=\"about\"><![CDATA[Lens Launcher is a unique, efficient way to browse and launch your apps.<br><br>Instead of scrolling long lists or swiping through multiple pages, Lens Launcher implements two unique features:<br><br><b>• An Equispaced Grid that displays all of your apps, regardless of screen size or app count.<br><br>• A Graphical Fisheye Lens to quickly zoom, pan and launch apps using touch gestures.</b><br><br>Lens Launcher also includes a full Settings menu to tweak all aspects of the Lens; Distortion, Scaling, Icon Size, Haptic Feedback, etc.<br><br>The Graphical Fisheye Lens algorithm is derived from methods proposed by Manojit Sarkar and Marc H. Brown. Their original 1993 paper, titled <i>Graphical Fisheye Views</i>, can be found <a href=\"https://drive.google.com/file/d/0B6Nqy9y098RLa2pqNVFUcUhIZXM/view?usp=sharing\">here</a>.<br><br>Lens Launcher is written by Nick Rout<br><a href=\"https://twitter.com/ricknout\">Twitter</a> | <a href=\"https://plus.google.com/+NicholasRout\">Google+</a><br><br>Major contributions have been made by Rish Bhardwaj<br><a href=\"http://rish.pythonanywhere.com/home\">Website</a> | <a href=\"http://www.linkedin.com/in/bhardwajrish/\">LinkedIn</a><br><br>The source code and resources are available on <a href=\"https://github.com/nicholasrout/lens-launcher\">Github</a><br><br>Check out <b>ShortStories</b> by Nick Rout. Interactive stories told through App Shortcuts and Notifications.<br><a href=\"https://play.google.com/store/apps/details?id=com.nickrout.shortstories\">Get it on Google Play</a>]]></string>\n    <string name=\"title_activity_main\">MainActivity</string>\n\n    <!-- PRO strings -->\n    <string name=\"pro\">PRO</string>\n    <string name=\"get_pro\">Get Lens Launcher PRO</string>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <!-- App Theme -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.DayNight.DarkActionBar\">\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n    <!-- Home (Launcher) Theme -->\n    <style name=\"HomeTheme\" parent=\"Theme.AppCompat.DayNight.NoActionBar\">\n        <item name=\"android:windowBackground\">@android:color/transparent</item>\n        <item name=\"android:colorBackgroundCacheHint\">@null</item>\n        <item name=\"android:windowShowWallpaper\">true</item>\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n        <item name=\"android:navigationBarColor\" tools:targetApi=\"21\">@android:color/transparent</item>\n        <item name=\"android:enforceNavigationBarContrast\" tools:targetApi=\"29\">false</item>\n    </style>\n\n    <!-- Settings Theme -->\n    <style name=\"AppTheme.NoActionBar\">\n        <item name=\"windowActionBar\">false</item>\n        <item name=\"windowNoTitle\">true</item>\n    </style>\n\n    <!-- App Bar Themes -->\n    <style name=\"AppTheme.AppBarOverlay\" parent=\"ThemeOverlay.AppCompat.Dark.ActionBar\" />\n    <style name=\"AppTheme.PopupOverlay\" parent=\"ThemeOverlay.AppCompat.Light\" />\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-land/dimen.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <!-- Lens Dimensions -->\n    <dimen name=\"offset_system_vertical\">30dp</dimen>\n    <dimen name=\"offset_system_horizontal\">80dp</dimen>\n    <dimen name=\"height_lens_preview\">240dp</dimen>\n\n</resources>"
  },
  {
    "path": "app/src/main/res/values-night/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <!-- View Colors -->\n    <color name=\"colorCircles\">@color/colorWhite</color>\n    <color name=\"colorAppTint\">@color/colorWhite</color>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-night/styles.xml",
    "content": "<resources>\n\n    <!-- App Bar Themes -->\n    <style name=\"AppTheme.PopupOverlay\" parent=\"ThemeOverlay.AppCompat.Dark\" />\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-w640dp/integers.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <integer name=\"columns_apps\">2</integer>\n</resources>"
  },
  {
    "path": "app/src/main/res/values-w820dp/dimen.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <!-- General -->\n    <dimen name=\"activity_horizontal_margin\">64dp</dimen>\n    <dimen name=\"activity_horizontal_margin_apps\">56dp</dimen>\n\n</resources>"
  },
  {
    "path": "app/src/main/res/xml/shortcuts.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shortcuts\n    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <shortcut\n        android:shortcutId=\"settings\"\n        android:enabled=\"true\"\n        android:icon=\"@drawable/ic_shortcut_settings\"\n        android:shortcutShortLabel=\"@string/activity_title_settings\"\n        android:shortcutLongLabel=\"@string/activity_title_settings\">\n        <intent\n            android:action=\"android.intent.action.VIEW\"\n            android:targetPackage=\"nickrout.lenslauncher\"\n            android:targetClass=\"nickrout.lenslauncher.ui.SettingsActivity\" />\n    </shortcut>\n\n    <shortcut\n        android:shortcutId=\"apps\"\n        android:enabled=\"true\"\n        android:icon=\"@drawable/ic_shortcut_apps\"\n        android:shortcutShortLabel=\"@string/activity_title_apps\"\n        android:shortcutLongLabel=\"@string/activity_title_apps\">\n        <intent\n            android:action=\"android.intent.action.VIEW\"\n            android:targetPackage=\"nickrout.lenslauncher\"\n            android:targetClass=\"nickrout.lenslauncher.ui.HomeActivity\" />\n    </shortcut>\n\n</shortcuts>"
  },
  {
    "path": "app/src/test/java/nickrout/lenslauncher/ExampleUnitTest.java",
    "content": "package nickrout.lenslauncher;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * To work on unit tests, switch the Test Artifact in the Build Variants view.\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "build.gradle",
    "content": "buildscript {\n    repositories {\n        google()\n        mavenCentral()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:8.2.2'\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        mavenCentral()\n        maven { url \"https://jitpack.io\" }\n    }\n}\n\ntasks.register('clean', Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: '2'\nservices:\n  gradle:\n    image: openjdk\n    working_dir: /app\n    environment:\n      - ANDROID_HOME=/app/android-studio\n    command: bash /app/docker-entrypoint.sh\n    volumes:\n      - '.:/app'\n      - '~/.gradle:/root/.gradle'\n"
  },
  {
    "path": "docker-entrypoint.sh",
    "content": "#! /bin/bash\n\nset -e;\n\ncd /app;\n\n# Ensure Android SDK is installed\nif [ ! -d /app/android-studio ]; then\n  echo \"Android SDK directory not found.\";\n\n  if [ ! -f /app/android-sdk.zip ]; then\n    echo \"Android SDK zip file not found; beginning download.\";\n\n    # Download the latest version of Android SDK\n    curl -L \"$( \\\n      curl -sL \"https://developer.android.com/studio/index.html\" \\\n        | grep -Eoh \"https?://.*?android-studio-ide.*?-linux\\.zip\" \\\n    )\" > /app/android-sdk.zip;\n\n  fi\n\n  # Unzips file to /app/android-studio\n  unzip /app/android-sdk.zip;\nfi\n\n# Sign Android SDK license\nif [ ! -d /app/android-studio/licenses/android-sdk-license ]; then\n  mkdir -p /app/android-studio/licenses;\n  echo -e \"\\n8933bad161af4178b1185d1a37fbf41ea5269c55\" \\\n    > /app/android-studio/licenses/android-sdk-license;\nfi\n\n# Generate self-signed cert\nkeytool -genkey -noprompt \\\n  -alias selfsigned \\\n  -dname \"CN=UNKNOWN, OU=UNKNOWN, O=UNKNOWN, L=UNKNOWN, S=UNKNOWN, C=UNKNOWN\" \\\n  -keystore /root/.keystore \\\n  -storepass password \\\n  -keypass password;\n\n# Create Lens Launcher APK\n/app/gradlew assembleRelease \\\n  -Pandroid.injected.signing.key.alias=selfsigned \\\n  -Pandroid.injected.signing.store.file=/root/.keystore \\\n  -Pandroid.injected.signing.store.password=password \\\n  -Pandroid.injected.signing.key.password=password;\n\n# Find the generated APK file in lens-launcher/app/build/outputs/apk/app-release.apk\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Wed Jan 31 16:09:16 SAST 2024\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.2-bin.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx10248m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n\nandroid.nonFinalResIds=false\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windowz variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\ngoto execute\r\n\r\n:4NT_args\r\n@rem Get arguments from the 4NT Shell from JP Software\r\nset CMD_LINE_ARGS=%$\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "settings.gradle",
    "content": "include ':app'\n"
  }
]