[
  {
    "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/\n\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\n/*/out\n/*/*/build\n/*/*/production\n*.iml\n*.iws\n*.ipr\n*~\n*.swp\n"
  },
  {
    "path": "README.md",
    "content": "Simple Launcher\n==============\n\nAn example custom launcher for Android, read more here: http://arnab.ch/blog/2013/08/how-to-write-custom-launcher-app-in-android/\n\n-------\nMIT License. Copyright 2016 Arnab Chakraborty. https://arnab.ch\n"
  },
  {
    "path": "SimpleLauncher/build.gradle",
    "content": "buildscript {\n    repositories {\n        jcenter();\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:4.0.0'\n    }\n}\napply plugin: 'com.android.application'\n\nrepositories {\n    jcenter();\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    implementation 'androidx.appcompat:appcompat:1.1.0'\n    implementation 'androidx.legacy:legacy-support-v4:1.0.0'\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test.ext:junit:1.1.1'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'\n}\n\nandroid {\n    compileSdkVersion 28\n    \n    defaultConfig {\n        minSdkVersion 19\n        targetSdkVersion 29\n    }\n}\n"
  },
  {
    "path": "SimpleLauncher/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    package=\"ch.arnab.simplelauncher\"\n    android:versionCode=\"1\"\n    android:versionName=\"1.0\">\n\n    <application\n        android:clearTaskOnLaunch=\"true\"\n        android:icon=\"@drawable/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:launchMode=\"singleTask\"\n        android:stateNotNeeded=\"true\"\n        android:theme=\"@style/AppTheme\"\n        tools:ignore=\"GoogleAppIndexingWarning\">\n        <activity\n            android:name=\"ch.arnab.simplelauncher.HomeScreen\"\n            android:excludeFromRecents=\"true\"\n            android:label=\"@string/app_name\"\n            android:launchMode=\"singleTask\"\n            android:screenOrientation=\"nosensor\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <!-- The following two intent-filters are the key to set homescreen -->\n                <category android:name=\"android.intent.category.HOME\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n            </intent-filter>\n        </activity>\n    </application>\n</manifest>\n"
  },
  {
    "path": "SimpleLauncher/src/main/java/ch/arnab/simplelauncher/AppListAdapter.java",
    "content": "package ch.arnab.simplelauncher;\n\nimport android.annotation.TargetApi;\nimport android.content.Context;\nimport android.os.Build;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ArrayAdapter;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\n\n/**\n * Created by Arnab Chakraborty\n */\npublic class AppListAdapter extends ArrayAdapter<AppModel> {\n    private final LayoutInflater mInflater;\n\n    public AppListAdapter (Context context) {\n        super(context, android.R.layout.simple_list_item_2);\n\n        mInflater = LayoutInflater.from(context);\n    }\n\n    public void setData(ArrayList<AppModel> data) {\n        clear();\n        if (data != null) {\n            addAll(data);\n        }\n    }\n\n    @Override\n    @TargetApi(Build.VERSION_CODES.HONEYCOMB)\n    public void addAll(Collection<? extends AppModel> items) {\n        //If the platform supports it, use addAll, otherwise add in loop\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {\n            super.addAll(items);\n        }else{\n            for(AppModel item: items){\n                super.add(item);\n            }\n        }\n    }\n\n    /**\n     * Populate new items in the list.\n     */\n    @Override public View getView(int position, View convertView, ViewGroup parent) {\n        View view;\n\n        if (convertView == null) {\n            view = mInflater.inflate(R.layout.list_item_icon_text, parent, false);\n        } else {\n            view = convertView;\n        }\n\n        AppModel item = getItem(position);\n        ((ImageView)view.findViewById(R.id.icon)).setImageDrawable(item.getIcon());\n        ((TextView)view.findViewById(R.id.text)).setText(item.getLabel());\n\n        return view;\n    }\n}\n"
  },
  {
    "path": "SimpleLauncher/src/main/java/ch/arnab/simplelauncher/AppListFragment.java",
    "content": "package ch.arnab.simplelauncher;\n\nimport android.os.Bundle;\nimport android.support.v4.app.ListFragment;\nimport android.support.v4.app.LoaderManager;\nimport android.support.v4.content.Loader;\nimport java.util.ArrayList;\n\n/**\n * Created by Arnab Chakraborty\n */\npublic class AppListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<ArrayList<AppModel>> {\n    AppListAdapter mAdapter;\n\n    @Override\n    public void onActivityCreated(Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n\n        setEmptyText(\"No Applications\");\n\n        mAdapter = new AppListAdapter(getActivity());\n        setListAdapter(mAdapter);\n\n        // till the data is loaded display a spinner\n        setListShown(false);\n\n        // create the loader to load the apps list in background\n        getLoaderManager().initLoader(0, null, this);\n    }\n\n    @Override\n    public Loader<ArrayList<AppModel>> onCreateLoader(int id, Bundle bundle) {\n        return new AppsLoader(getActivity());\n    }\n\n    @Override\n    public void onLoadFinished(Loader<ArrayList<AppModel>> loader, ArrayList<AppModel> apps) {\n        mAdapter.setData(apps);\n\n        if (isResumed()) {\n            setListShown(true);\n        } else {\n            setListShownNoAnimation(true);\n        }\n    }\n\n    @Override\n    public void onLoaderReset(Loader<ArrayList<AppModel>> loader) {\n        mAdapter.setData(null);\n    }\n}\n"
  },
  {
    "path": "SimpleLauncher/src/main/java/ch/arnab/simplelauncher/AppModel.java",
    "content": "package ch.arnab.simplelauncher;\n\nimport android.content.Context;\nimport android.content.pm.ApplicationInfo;\nimport android.graphics.drawable.Drawable;\n\nimport java.io.File;\n\n/**\n * @credit http://developer.android.com/reference/android/content/AsyncTaskLoader.html\n */\npublic class AppModel {\n\n    private final Context mContext;\n    private final ApplicationInfo mInfo;\n\n    private String mAppLabel;\n    private Drawable mIcon;\n\n    private boolean mMounted;\n    private final File mApkFile;\n\n    public AppModel(Context context, ApplicationInfo info) {\n        mContext = context;\n        mInfo = info;\n\n        mApkFile = new File(info.sourceDir);\n    }\n\n    public ApplicationInfo getAppInfo() {\n        return mInfo;\n    }\n\n    public String getApplicationPackageName() {\n        return getAppInfo().packageName;\n    }\n\n    public String getLabel() {\n        return mAppLabel;\n    }\n\n    public Drawable getIcon() {\n        if (mIcon == null) {\n            if (mApkFile.exists()) {\n                mIcon = mInfo.loadIcon(mContext.getPackageManager());\n                return mIcon;\n            } else {\n                mMounted = false;\n            }\n        } else if (!mMounted) {\n            // If the app wasn't mounted but is now mounted, reload\n            // its icon.\n            if (mApkFile.exists()) {\n                mMounted = true;\n                mIcon = mInfo.loadIcon(mContext.getPackageManager());\n                return mIcon;\n            }\n        } else {\n            return mIcon;\n        }\n\n        return mContext.getResources().getDrawable(android.R.drawable.sym_def_app_icon);\n    }\n\n\n    void loadLabel(Context context) {\n        if (mAppLabel == null || !mMounted) {\n            if (!mApkFile.exists()) {\n                mMounted = false;\n                mAppLabel = mInfo.packageName;\n            } else {\n                mMounted = true;\n                CharSequence label = mInfo.loadLabel(context.getPackageManager());\n                mAppLabel = label != null ? label.toString() : mInfo.packageName;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "SimpleLauncher/src/main/java/ch/arnab/simplelauncher/AppsGridFragment.java",
    "content": "package ch.arnab.simplelauncher;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v4.app.LoaderManager;\nimport android.support.v4.content.Loader;\nimport android.view.View;\nimport android.widget.GridView;\n\nimport java.util.ArrayList;\n\n/**\n * Created by Arnab Chakraborty\n */\npublic class AppsGridFragment extends GridFragment implements LoaderManager.LoaderCallbacks<ArrayList<AppModel>> {\n\n    AppListAdapter mAdapter;\n\n    @Override\n    public void onActivityCreated(Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n\n        setEmptyText(\"No Applications\");\n\n        mAdapter = new AppListAdapter(getActivity());\n        setGridAdapter(mAdapter);\n\n        // till the data is loaded display a spinner\n        setGridShown(false);\n\n        // create the loader to load the apps list in background\n        getLoaderManager().initLoader(0, null, this);\n    }\n\n    @Override\n    public Loader<ArrayList<AppModel>> onCreateLoader(int id, Bundle bundle) {\n        return new AppsLoader(getActivity());\n    }\n\n    @Override\n    public void onLoadFinished(Loader<ArrayList<AppModel>> loader, ArrayList<AppModel> apps) {\n        mAdapter.setData(apps);\n\n        if (isResumed()) {\n            setGridShown(true);\n        } else {\n            setGridShownNoAnimation(true);\n        }\n    }\n\n    @Override\n    public void onLoaderReset(Loader<ArrayList<AppModel>> loader) {\n        mAdapter.setData(null);\n    }\n\n    @Override\n    public void onGridItemClick(GridView g, View v, int position, long id) {\n        AppModel app = (AppModel) getGridAdapter().getItem(position);\n        if (app != null) {\n            Intent intent = getActivity().getPackageManager().getLaunchIntentForPackage(app.getApplicationPackageName());\n\n            if (intent != null) {\n                startActivity(intent);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "SimpleLauncher/src/main/java/ch/arnab/simplelauncher/AppsLoader.java",
    "content": "package ch.arnab.simplelauncher;\n\nimport android.content.Context;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageManager;\nimport android.support.v4.content.AsyncTaskLoader;\n\nimport java.text.Collator;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Comparator;\n\n/**\n * @credit http://developer.android.com/reference/android/content/AsyncTaskLoader.html\n */\npublic class AppsLoader extends AsyncTaskLoader<ArrayList<AppModel>> {\n    ArrayList<AppModel> mInstalledApps;\n\n    final PackageManager mPm;\n    PackageIntentReceiver mPackageObserver;\n\n    public AppsLoader(Context context) {\n        super(context);\n\n        mPm = context.getPackageManager();\n    }\n\n    @Override\n    public ArrayList<AppModel> loadInBackground() {\n        // retrieve the list of installed applications\n        List<ApplicationInfo> apps = mPm.getInstalledApplications(0);\n\n        if (apps == null) {\n            apps = new ArrayList<ApplicationInfo>();\n        }\n\n        final Context context = getContext();\n\n        // create corresponding apps and load their labels\n        ArrayList<AppModel> items = new ArrayList<AppModel>(apps.size());\n        for (int i = 0; i < apps.size(); i++) {\n            String pkg = apps.get(i).packageName;\n\n            // only apps which are launchable\n            if (context.getPackageManager().getLaunchIntentForPackage(pkg) != null) {\n                AppModel app = new AppModel(context, apps.get(i));\n                app.loadLabel(context);\n                items.add(app);\n            }\n        }\n\n        // sort the list\n        Collections.sort(items, ALPHA_COMPARATOR);\n\n        return items;\n    }\n\n    @Override\n    public void deliverResult(ArrayList<AppModel> apps) {\n        if (isReset()) {\n            // An async query came in while the loader is stopped.  We\n            // don't need the result.\n            if (apps != null) {\n                onReleaseResources(apps);\n            }\n        }\n\n        ArrayList<AppModel> oldApps = apps;\n        mInstalledApps = apps;\n\n        if (isStarted()) {\n            // If the Loader is currently started, we can immediately\n            // deliver its results.\n            super.deliverResult(apps);\n        }\n\n        // At this point we can release the resources associated with\n        // 'oldApps' if needed; now that the new result is delivered we\n        // know that it is no longer in use.\n        if (oldApps != null) {\n            onReleaseResources(oldApps);\n        }\n    }\n\n    @Override\n    protected void onStartLoading() {\n        if (mInstalledApps != null) {\n            // If we currently have a result available, deliver it\n            // immediately.\n            deliverResult(mInstalledApps);\n        }\n\n        // watch for changes in app install and uninstall operation\n        if (mPackageObserver == null) {\n            mPackageObserver = new PackageIntentReceiver(this);\n        }\n\n        if (takeContentChanged() || mInstalledApps == null ) {\n            // If the data has changed since the last time it was loaded\n            // or is not currently available, start a load.\n            forceLoad();\n        }\n    }\n\n    @Override\n    protected void onStopLoading() {\n        // Attempt to cancel the current load task if possible.\n        cancelLoad();\n    }\n\n    @Override\n    public void onCanceled(ArrayList<AppModel> apps) {\n        super.onCanceled(apps);\n\n        // At this point we can release the resources associated with 'apps'\n        // if needed.\n        onReleaseResources(apps);\n    }\n\n    @Override\n    protected void onReset() {\n        // Ensure the loader is stopped\n        onStopLoading();\n\n        // At this point we can release the resources associated with 'apps'\n        // if needed.\n        if (mInstalledApps != null) {\n            onReleaseResources(mInstalledApps);\n            mInstalledApps = null;\n        }\n\n        // Stop monitoring for changes.\n        if (mPackageObserver != null) {\n            getContext().unregisterReceiver(mPackageObserver);\n            mPackageObserver = null;\n        }\n    }\n\n    /**\n     * Helper method to do the cleanup work if needed, for example if we're\n     * using Cursor, then we should be closing it here\n     *\n     * @param apps\n     */\n    protected void onReleaseResources(ArrayList<AppModel> apps) {\n        // do nothing\n    }\n\n\n    /**\n     * Perform alphabetical comparison of application entry objects.\n     */\n    public static final Comparator<AppModel> ALPHA_COMPARATOR = new Comparator<AppModel>() {\n        private final Collator sCollator = Collator.getInstance();\n        @Override\n        public int compare(AppModel object1, AppModel object2) {\n            return sCollator.compare(object1.getLabel(), object2.getLabel());\n        }\n    };\n}\n"
  },
  {
    "path": "SimpleLauncher/src/main/java/ch/arnab/simplelauncher/GridFragment.java",
    "content": "package ch.arnab.simplelauncher;\n\n/*\n * Created by Thomas Barrasso on 9/11/12.\n * Copyright (c) 2012 Loupe Inc.\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 */\n\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.support.v4.app.Fragment;\nimport android.util.TypedValue;\nimport android.view.Gravity;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.view.animation.AnimationUtils;\nimport android.widget.AdapterView;\nimport android.widget.FrameLayout;\nimport android.widget.GridView;\nimport android.widget.LinearLayout;\nimport android.widget.ListAdapter;\nimport android.widget.ListView;\nimport android.widget.ProgressBar;\nimport android.widget.TextView;\n\n/**\n * Based on {@link android.app.ListFragment} but adapted for {@link GridView}.\n */\npublic class GridFragment extends Fragment {\n\n    static final int INTERNAL_EMPTY_ID = 0x00ff0001;\n    static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002;\n    static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;\n\n    final private Handler mHandler = new Handler();\n\n    final private Runnable mRequestFocus = new Runnable() {\n        public void run() {\n            mGrid.focusableViewAvailable(mGrid);\n        }\n    };\n\n    final private AdapterView.OnItemClickListener mOnClickListener\n            = new AdapterView.OnItemClickListener() {\n        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {\n            onGridItemClick((GridView) parent, v, position, id);\n        }\n    };\n\n    ListAdapter mAdapter;\n    GridView mGrid;\n    View mEmptyView;\n    TextView mStandardEmptyView;\n    View mProgressContainer;\n    View mGridContainer;\n    CharSequence mEmptyText;\n    boolean mGridShown;\n\n    public GridFragment() { }\n\n    /**\n     * Provide default implementation to return a simple grid view.  Subclasses\n     * can override to replace with their own layout.  If doing so, the\n     * returned view hierarchy <em>must</em> have a GridView whose id\n     * is {@link android.R.id#list android.R.id.list} and can optionally\n     * have a sibling view id {@link android.R.id#empty android.R.id.empty}\n     * that is to be shown when the grid is empty.\n     *\n     * <p>If you are overriding this method with your own custom content,\n     * consider including the standard layout {@link android.R.layout#list_content}\n     * in your layout file, so that you continue to retain all of the standard\n     * behavior of ListFragment.  In particular, this is currently the only\n     * way to have the built-in indeterminant progress state be shown.\n     */\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container,\n                             Bundle savedInstanceState) {\n        final Context context = getActivity();\n\n        FrameLayout root = new FrameLayout(context);\n\n        // ------------------------------------------------------------------\n\n        LinearLayout pframe = new LinearLayout(context);\n        pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);\n        pframe.setOrientation(LinearLayout.VERTICAL);\n        pframe.setVisibility(View.GONE);\n        pframe.setGravity(Gravity.CENTER);\n\n        ProgressBar progress = new ProgressBar(context, null,\n                android.R.attr.progressBarStyleLarge);\n        pframe.addView(progress, new FrameLayout.LayoutParams(\n                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));\n\n        root.addView(pframe, new FrameLayout.LayoutParams(\n                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));\n\n        // ------------------------------------------------------------------\n\n        FrameLayout lframe = new FrameLayout(context);\n        lframe.setId(INTERNAL_LIST_CONTAINER_ID);\n\n        TextView tv = new TextView(getActivity());\n        tv.setId(INTERNAL_EMPTY_ID);\n        tv.setGravity(Gravity.CENTER);\n        lframe.addView(tv, new FrameLayout.LayoutParams(\n                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));\n\n        GridView lv = new GridView(getActivity());\n        lv.setId(android.R.id.list);\n        lv.setDrawSelectorOnTop(false);\n        lv.setColumnWidth(convertDpToPixels(60, getActivity()));\n        lv.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);\n        lv.setNumColumns(GridView.AUTO_FIT);\n        lv.setHorizontalSpacing(convertDpToPixels(20, getActivity()));\n        lv.setVerticalSpacing(convertDpToPixels(20, getActivity()));\n        lv.setSmoothScrollbarEnabled(true);\n\n        // disable overscroll\n        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {\n            lv.setOverScrollMode(ListView.OVER_SCROLL_NEVER);\n        }\n\n        lframe.addView(lv, new FrameLayout.LayoutParams(\n                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));\n\n        root.addView(lframe, new FrameLayout.LayoutParams(\n                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));\n\n        // ------------------------------------------------------------------\n\n        root.setLayoutParams(new FrameLayout.LayoutParams(\n                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));\n\n        return root;\n    }\n\n    /**\n     * Attach to grid view once the view hierarchy has been created.\n     */\n    @Override\n    public void onViewCreated(View view, Bundle savedInstanceState) {\n        super.onViewCreated(view, savedInstanceState);\n        ensureGrid();\n    }\n\n    /**\n     * Detach from {@link GridView}\n     */\n    @Override\n    public void onDestroyView() {\n        mHandler.removeCallbacks(mRequestFocus);\n        mGrid = null;\n        mGridShown = false;\n        mEmptyView = mProgressContainer = mGridContainer = null;\n        mStandardEmptyView = null;\n        super.onDestroyView();\n    }\n\n    public static int convertDpToPixels(float dp, Context context){\n        Resources resources = context.getResources();\n        return (int) TypedValue.applyDimension(\n                TypedValue.COMPLEX_UNIT_DIP,\n                dp,\n                resources.getDisplayMetrics()\n        );\n    }\n\n    /**\n     * This method will be called when an item in the grid is selected.\n     * Subclasses should override. Subclasses can call\n     * getGridView().getItemAtPosition(position) if they need to access the\n     * data associated with the selected item.\n     *\n     * @param g The {@link GridView} where the click happened\n     * @param v The view that was clicked within the {@link GridView}\n     * @param position The position of the view in the grid\n     * @param id The row id of the item that was clicked\n     */\n    public void onGridItemClick(GridView g, View v, int position, long id) {\n\n    }\n\n    /**\n     * Provide the cursor for the {@link GridView}.\n     */\n    public void setGridAdapter(ListAdapter adapter) {\n        final boolean hadAdapter = (mAdapter != null);\n        mAdapter = adapter;\n        if (mGrid != null) {\n            mGrid.setAdapter(adapter);\n            if (!mGridShown && !hadAdapter) {\n                // The grid was hidden, and previously didn't have an\n                // adapter.  It is now time to show it.\n                setGridShown(true, (getView().getWindowToken() != null));\n            }\n        }\n    }\n\n    /**\n     * Set the currently selected grid item to the specified\n     * position with the adapter's data\n     *\n     * @param position\n     */\n    public void setSelection(int position) {\n        ensureGrid();\n        mGrid.setSelection(position);\n    }\n\n    /**\n     * Get the position of the currently selected grid item.\n     */\n    public int getSelectedItemPosition() {\n        ensureGrid();\n        return mGrid.getSelectedItemPosition();\n    }\n\n    /**\n     * Get the cursor row ID of the currently selected grid item.\n     */\n    public long getSelectedItemId() {\n        ensureGrid();\n        return mGrid.getSelectedItemId();\n    }\n\n    /**\n     * Get the activity's {@link GridView} widget.\n     */\n    public GridView getGridView() {\n        ensureGrid();\n        return mGrid;\n    }\n\n    /**\n     * The default content for a ListFragment has a TextView that can\n     * be shown when the grid is empty.  If you would like to have it\n     * shown, call this method to supply the text it should use.\n     */\n    public void setEmptyText(CharSequence text) {\n        ensureGrid();\n        if (mStandardEmptyView == null) {\n            throw new IllegalStateException(\"Can't be used with a custom content view\");\n        }\n        mStandardEmptyView.setText(text);\n        if (mEmptyText == null) {\n            mGrid.setEmptyView(mStandardEmptyView);\n        }\n        mEmptyText = text;\n    }\n\n    /**\n     * Control whether the grid is being displayed.  You can make it not\n     * displayed if you are waiting for the initial data to show in it.  During\n     * this time an indeterminant progress indicator will be shown instead.\n     *\n     * <p>Applications do not normally need to use this themselves.  The default\n     * behavior of ListFragment is to start with the grid not being shown, only\n     * showing it once an adapter is given with {@link #setGridAdapter(ListAdapter)}.\n     * If the grid at that point had not been shown, when it does get shown\n     * it will be do without the user ever seeing the hidden state.\n     *\n     * @param shown If true, the grid view is shown; if false, the progress\n     * indicator.  The initial value is true.\n     */\n    public void setGridShown(boolean shown) {\n        setGridShown(shown, true);\n    }\n\n    /**\n     * Like {@link #setGridShown(boolean)}, but no animation is used when\n     * transitioning from the previous state.\n     */\n    public void setGridShownNoAnimation(boolean shown) {\n        setGridShown(shown, false);\n    }\n\n    /**\n     * Control whether the grid is being displayed.  You can make it not\n     * displayed if you are waiting for the initial data to show in it.  During\n     * this time an indeterminant progress indicator will be shown instead.\n     *\n     * @param shown If true, the grid view is shown; if false, the progress\n     * indicator.  The initial value is true.\n     * @param animate If true, an animation will be used to transition to the\n     * new state.\n     */\n    private void setGridShown(boolean shown, boolean animate) {\n        ensureGrid();\n        if (mProgressContainer == null) {\n            throw new IllegalStateException(\"Can't be used with a custom content view\");\n        }\n        if (mGridShown == shown) {\n            return;\n        }\n        mGridShown = shown;\n        if (shown) {\n            if (animate) {\n                mProgressContainer.startAnimation(AnimationUtils.loadAnimation(\n                        getActivity(), android.R.anim.fade_out));\n                mGridContainer.startAnimation(AnimationUtils.loadAnimation(\n                        getActivity(), android.R.anim.fade_in));\n            } else {\n                mProgressContainer.clearAnimation();\n                mGridContainer.clearAnimation();\n            }\n            mProgressContainer.setVisibility(View.GONE);\n            mGridContainer.setVisibility(View.VISIBLE);\n        } else {\n            if (animate) {\n                mProgressContainer.startAnimation(AnimationUtils.loadAnimation(\n                        getActivity(), android.R.anim.fade_in));\n                mGridContainer.startAnimation(AnimationUtils.loadAnimation(\n                        getActivity(), android.R.anim.fade_out));\n            } else {\n                mProgressContainer.clearAnimation();\n                mGridContainer.clearAnimation();\n            }\n            mProgressContainer.setVisibility(View.VISIBLE);\n            mGridContainer.setVisibility(View.GONE);\n        }\n    }\n\n    /**\n     * Get the ListAdapter associated with this activity's {@link GridView}.\n     */\n    public ListAdapter getGridAdapter() {\n        return mAdapter;\n    }\n\n    private void ensureGrid() {\n        if (mGrid != null) {\n            return;\n        }\n        View root = getView();\n        if (root == null) {\n            throw new IllegalStateException(\"Content view not yet created\");\n        }\n        if (root instanceof GridView) {\n            mGrid = (GridView) root;\n        } else {\n            mStandardEmptyView = (TextView)root.findViewById(INTERNAL_EMPTY_ID);\n            if (mStandardEmptyView == null) {\n                mEmptyView = root.findViewById(android.R.id.empty);\n            } else {\n                mStandardEmptyView.setVisibility(View.GONE);\n            }\n            mProgressContainer = root.findViewById(INTERNAL_PROGRESS_CONTAINER_ID);\n            mGridContainer = root.findViewById(INTERNAL_LIST_CONTAINER_ID);\n            View rawGridView = root.findViewById(android.R.id.list);\n            if (!(rawGridView instanceof GridView)) {\n                if (rawGridView == null) {\n                    throw new RuntimeException(\n                            \"Your content must have a GridView whose id attribute is \" +\n                                    \"'android.R.id.list'\");\n                }\n                throw new RuntimeException(\n                        \"Content has view with id attribute 'android.R.id.list' \"\n                                + \"that is not a GridView class\");\n            }\n            mGrid = (GridView) rawGridView;\n            if (mEmptyView != null) {\n                mGrid.setEmptyView(mEmptyView);\n            } else if (mEmptyText != null) {\n                mStandardEmptyView.setText(mEmptyText);\n                mGrid.setEmptyView(mStandardEmptyView);\n            }\n        }\n        mGridShown = true;\n        mGrid.setOnItemClickListener(mOnClickListener);\n        if (mAdapter != null) {\n            ListAdapter adapter = mAdapter;\n            mAdapter = null;\n            setGridAdapter(adapter);\n        } else {\n            // We are starting without an adapter, so assume we won't\n            // have our data right away and start with the progress indicator.\n            if (mProgressContainer != null) {\n                setGridShown(false, false);\n            }\n        }\n        mHandler.post(mRequestFocus);\n    }\n}\n"
  },
  {
    "path": "SimpleLauncher/src/main/java/ch/arnab/simplelauncher/HomeScreen.java",
    "content": "package ch.arnab.simplelauncher;\n\nimport android.os.Bundle;\nimport android.app.Activity;\nimport android.support.v4.app.FragmentActivity;\nimport android.view.Menu;\n\npublic class HomeScreen extends FragmentActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.homescreen);\n    }\n\n\n    @Override\n    public boolean onCreateOptionsMenu(Menu menu) {\n        // Inflate the menu; this adds items to the action bar if it is present.\n        getMenuInflater().inflate(R.menu.home_screen, menu);\n        return true;\n    }\n}\n"
  },
  {
    "path": "SimpleLauncher/src/main/java/ch/arnab/simplelauncher/PackageIntentReceiver.java",
    "content": "package ch.arnab.simplelauncher;\n\nimport android.content.BroadcastReceiver;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.IntentFilter;\n\n/**\n * Helper class to look for interesting changes to the installed apps\n * so that the loader can be updated.\n *\n * @Credit http://developer.android.com/reference/android/content/AsyncTaskLoader.html\n */\npublic class PackageIntentReceiver extends BroadcastReceiver {\n\n    final AppsLoader mLoader;\n\n    public PackageIntentReceiver(AppsLoader loader) {\n        mLoader = loader;\n\n        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);\n        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);\n        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);\n        filter.addDataScheme(\"package\");\n        mLoader.getContext().registerReceiver(this, filter);\n\n        // Register for events related to sdcard installation.\n        IntentFilter sdFilter = new IntentFilter();\n        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);\n        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);\n        mLoader.getContext().registerReceiver(this, sdFilter);\n    }\n\n    @Override public void onReceive(Context context, Intent intent) {\n        // Tell the loader about the change.\n        mLoader.onContentChanged();\n    }\n\n}\n"
  },
  {
    "path": "SimpleLauncher/src/main/res/layout/homescreen.xml",
    "content": "<RelativeLayout 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    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n    android:paddingTop=\"@dimen/activity_vertical_margin\"\n    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n    tools:context=\".HomeScreen\">\n\n    <fragment\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:name=\"ch.arnab.simplelauncher.AppsGridFragment\"\n            android:id=\"@+id/apps_grid\" />\n\n</RelativeLayout>\n"
  },
  {
    "path": "SimpleLauncher/src/main/res/layout/list_item_icon_text.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2007 The Android Open Source Project\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-->\n\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              android:orientation=\"vertical\"\n              android:layout_width=\"match_parent\"\n              android:layout_height=\"match_parent\">\n\n    <ImageView android:id=\"@+id/icon\"\n               android:layout_width=\"48dp\"\n               android:layout_height=\"48dp\"\n               android:layout_gravity=\"center_horizontal\"/>\n\n    <TextView android:id=\"@+id/text\"\n              android:layout_gravity=\"center_horizontal\"\n              android:layout_width=\"wrap_content\"\n              android:layout_height=\"wrap_content\"\n              android:ellipsize=\"end\"\n              android:singleLine=\"true\"\n              android:gravity=\"center\"\n              android:textColor=\"@android:color/white\"\n              android:textSize=\"14sp\"\n              />\n\n</LinearLayout>"
  },
  {
    "path": "SimpleLauncher/src/main/res/menu/home_screen.xml",
    "content": "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <item\n        android:id=\"@+id/action_settings\"\n        android:orderInCategory=\"100\"\n        android:title=\"@string/action_settings\"\n        app:showAsAction=\"never\" />\n</menu>\n"
  },
  {
    "path": "SimpleLauncher/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "SimpleLauncher/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <string name=\"app_name\">SimpleLauncher</string>\n    <string name=\"action_settings\">Settings</string>\n    <string name=\"hello_world\">Hello world!</string>\n\n</resources>\n"
  },
  {
    "path": "SimpleLauncher/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!--\n        Base application theme, dependent on API level. This theme is replaced\n        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.\n    -->\n    <style name=\"AppBaseTheme\" parent=\"android:Theme.Wallpaper.NoTitleBar\">\n        <!--\n            Theme customizations available in newer API levels can go in\n            res/values-vXX/styles.xml, while customizations related to\n            backward-compatibility can go here.\n        -->\n    </style>\n\n    <!-- Application theme. -->\n    <style name=\"AppTheme\" parent=\"AppBaseTheme\">\n        <!-- All customizations that are NOT specific to a particular API-level can go here. -->\n    </style>\n\n</resources>\n"
  },
  {
    "path": "SimpleLauncher/src/main/res/values-sw600dp/dimens.xml",
    "content": "<resources>\n    <!-- Customize dimensions originally defined in res/values/dimens.xml (such as\n         screen margins) for sw600dp devices (e.g. 7\" tablets) here. -->\n</resources>\n"
  },
  {
    "path": "SimpleLauncher/src/main/res/values-sw720dp-land/dimens.xml",
    "content": "<resources>\n    <!-- Customize dimensions originally defined in res/values/dimens.xml (such as\n         screen margins) for sw720dp devices (e.g. 10\" tablets) in landscape here. -->\n    <dimen name=\"activity_horizontal_margin\">128dp</dimen>\n</resources>\n"
  },
  {
    "path": "SimpleLauncher/src/main/res/values-v11/styles.xml",
    "content": "<resources>\n\n    <!--\n        Base application theme for API 11+. This theme completely replaces\n        AppBaseTheme from res/values/styles.xml on API 11+ devices.\n    -->\n    <!--<style name=\"AppBaseTheme\" parent=\"android:Theme.Holo.Light\">-->\n        <!--&lt;!&ndash; API 11 theme customizations can go here. &ndash;&gt;-->\n    <!--</style>-->\n\n</resources>\n"
  },
  {
    "path": "SimpleLauncher/src/main/res/values-v14/styles.xml",
    "content": "<resources>\n\n    <!--\n        Base application theme for API 14+. This theme completely replaces\n        AppBaseTheme from BOTH res/values/styles.xml and\n        res/values-v11/styles.xml on API 14+ devices.\n    -->\n\n\n</resources>\n"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Sun Mar 16 17:01:50 GMT+05:30 2014\ndistributionBase = GRADLE_USER_HOME\ndistributionPath = wrapper/dists\nzipStoreBase = GRADLE_USER_HOME\nzipStorePath = wrapper/dists\ndistributionUrl = https\\://services.gradle.org/distributions/gradle-6.1.1-all.zip\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# For Cygwin, ensure paths are in UNIX format before anything is touched.\nif $cygwin ; then\n    [ -n \"$JAVA_HOME\" ] && JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\nfi\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\\\"`/\" >&-\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >&-\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\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 ':SimpleLauncher'\n"
  }
]