[
  {
    "path": ".github/workflows/issue.yml",
    "content": "name: Notify\non:\n  issues:\n    types: [opened]\n  issue_comment:\n    types: [created]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - name: Notify\n        run: curl --location --request POST 'https://api.finogeeks.club/api/v1/finstore/webhooks/61b331d79b3dad0001f72fa2/postreceive?nonce=jhd2QyrArsc' --header \"Content-Type:application/json\" --data-raw '{\"msg\":\"仓库 ${{github.repository}} 有新的 issue\"}'\n"
  },
  {
    "path": ".github/workflows/pull_request.yml",
    "content": "name: Notify\non:\n  pull_request:\n    branches: [ master ]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - name: Notify\n        run: curl --location --request POST 'https://api.finogeeks.club/api/v1/finstore/webhooks/61b331d79b3dad0001f72fa2/postreceive?nonce=jhd2QyrArsc' --header \"Content-Type:application/json\" --data-raw '{\"msg\":\"仓库 ${{github.repository}} 有新的 PR ${{ github.event.pull_request._links.html.href }}\"}'\n"
  },
  {
    "path": ".gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n/.idea/caches\n/.idea/libraries\n/.idea/modules.xml\n/.idea/workspace.xml\n/.idea/navEditor.xml\n/.idea/assetWizardSettings.xml\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n.cxx\n"
  },
  {
    "path": ".idea/.name",
    "content": "mopdemo"
  },
  {
    "path": ".idea/codeStyles/Project.xml",
    "content": "<component name=\"ProjectCodeStyleConfiguration\">\n  <code_scheme name=\"Project\" version=\"173\">\n    <codeStyleSettings language=\"XML\">\n      <arrangement>\n        <rules>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>xmlns:android</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>xmlns:.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*:id</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*:name</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>name</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>style</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>ANDROID_ATTRIBUTE_ORDER</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>.*</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n        </rules>\n      </arrangement>\n    </codeStyleSettings>\n  </code_scheme>\n</component>"
  },
  {
    "path": ".idea/compiler.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <bytecodeTargetLevel target=\"11\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/deploymentTargetDropDown.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"deploymentTargetDropDown\">\n    <runningDeviceTargetSelectedWithDropDown>\n      <Target>\n        <type value=\"RUNNING_DEVICE_TARGET\" />\n        <deviceKey>\n          <Key>\n            <type value=\"SERIAL_NUMBER\" />\n            <value value=\"FA7AZ1A07148\" />\n          </Key>\n        </deviceKey>\n      </Target>\n    </runningDeviceTargetSelectedWithDropDown>\n    <timeTargetWasSelectedWithDropDown value=\"2022-10-24T09:17:42.427931Z\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/deploymentTargetSelector.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"deploymentTargetSelector\">\n    <selectionStates>\n      <SelectionState runConfigName=\"app\">\n        <option name=\"selectionMode\" value=\"DROPDOWN\" />\n      </SelectionState>\n    </selectionStates>\n  </component>\n</project>"
  },
  {
    "path": ".idea/gradle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleMigrationSettings\" migrationVersion=\"1\" />\n  <component name=\"GradleSettings\">\n    <option name=\"linkedExternalProjectsSettings\">\n      <GradleProjectSettings>\n        <option name=\"testRunner\" value=\"CHOOSE_PER_TEST\" />\n        <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n        <option name=\"gradleJvm\" value=\"#GRADLE_LOCAL_JAVA_HOME\" />\n        <option name=\"modules\">\n          <set>\n            <option value=\"$PROJECT_DIR$\" />\n            <option value=\"$PROJECT_DIR$/app\" />\n          </set>\n        </option>\n        <option name=\"resolveExternalAnnotations\" value=\"false\" />\n      </GradleProjectSettings>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/jarRepositories.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RemoteRepositoriesConfiguration\">\n    <remote-repository>\n      <option name=\"id\" value=\"central\" />\n      <option name=\"name\" value=\"Maven Central repository\" />\n      <option name=\"url\" value=\"https://repo1.maven.org/maven2\" />\n    </remote-repository>\n    <remote-repository>\n      <option name=\"id\" value=\"jboss.community\" />\n      <option name=\"name\" value=\"JBoss Community repository\" />\n      <option name=\"url\" value=\"https://repository.jboss.org/nexus/content/repositories/public/\" />\n    </remote-repository>\n    <remote-repository>\n      <option name=\"id\" value=\"maven\" />\n      <option name=\"name\" value=\"maven\" />\n      <option name=\"url\" value=\"https://gradle.finogeeks.club/repository/applet/\" />\n    </remote-repository>\n    <remote-repository>\n      <option name=\"id\" value=\"BintrayJCenter\" />\n      <option name=\"name\" value=\"BintrayJCenter\" />\n      <option name=\"url\" value=\"https://jcenter.bintray.com/\" />\n    </remote-repository>\n    <remote-repository>\n      <option name=\"id\" value=\"Google\" />\n      <option name=\"name\" value=\"Google\" />\n      <option name=\"url\" value=\"https://dl.google.com/dl/android/maven2/\" />\n    </remote-repository>\n  </component>\n</project>"
  },
  {
    "path": ".idea/kotlinc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"KotlinJpsPluginSettings\">\n    <option name=\"version\" value=\"1.7.22\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/migrations.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectMigrations\">\n    <option name=\"MigrateToGradleLocalJavaHome\">\n      <set>\n        <option value=\"$PROJECT_DIR$\" />\n      </set>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CMakeSettings\">\n    <configurations>\n      <configuration PROFILE_NAME=\"Debug\" CONFIG_NAME=\"Debug\" />\n    </configurations>\n  </component>\n  <component name=\"DesignSurface\">\n    <option name=\"filePathToZoomLevelMap\">\n      <map>\n        <entry key=\"app/src/main/res/layout/activity_main.xml\" value=\"0.34427083333333336\" />\n        <entry key=\"app/src/main/res/layout/activity_scan_qr_code.xml\" value=\"0.12135416666666667\" />\n        <entry key=\"app/src/main/res/layout/activity_scan_start_applet.xml\" value=\"0.20244565217391305\" />\n      </map>\n    </option>\n  </component>\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_11\" default=\"true\" project-jdk-name=\"corretto-11\" project-jdk-type=\"JavaSDK\">\n    <output url=\"file://$PROJECT_DIR$/build/classes\" />\n  </component>\n  <component name=\"ProjectType\">\n    <option name=\"id\" value=\"Android\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/runConfigurations.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <option name=\"ignoredProducers\">\n      <set>\n        <option value=\"com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer\" />\n        <option value=\"com.intellij.execution.junit.AllInPackageConfigurationProducer\" />\n        <option value=\"com.intellij.execution.junit.PatternConfigurationProducer\" />\n        <option value=\"com.intellij.execution.junit.TestInClassConfigurationProducer\" />\n        <option value=\"com.intellij.execution.junit.UniqueIdConfigurationProducer\" />\n        <option value=\"com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer\" />\n        <option value=\"org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer\" />\n        <option value=\"org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer\" />\n      </set>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n    <a href=\"https://www.finclip.com?from=github\">\n    <img width=\"auto\" src=\"https://www.finclip.com/mop/document/images/logo.png\">\n    </a>\n</p>\n\n<p align=\"center\"> \n    <strong>FinClip Android DEMO</strong></br>\n<p>\n<p align=\"center\"> \n        本项目提供在 Android 环境中运行小程序的 DEMO 样例\n<p>\n\n<p align=\"center\"> \n\t👉 <a href=\"https://www.finclip.com?from=github\">https://www.finclip.com/</a> 👈\n</p>\n\n<div align=\"center\">\n\n<a href=\"#\"><img src=\"https://img.shields.io/badge/%E4%B8%93%E5%B1%9E%E5%BC%80%E5%8F%91%E8%80%85-20000%2B-brightgreen\"></a>\n<a href=\"#\"><img src=\"https://img.shields.io/badge/%E5%B7%B2%E4%B8%8A%E6%9E%B6%E5%B0%8F%E7%A8%8B%E5%BA%8F-6000%2B-blue\"></a>\n<a href=\"#\"><img src=\"https://img.shields.io/badge/%E5%B7%B2%E9%9B%86%E6%88%90%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%BA%94%E7%94%A8-75%2B-yellow\"></a>\n<a href=\"#\"><img src=\"https://img.shields.io/badge/%E5%AE%9E%E9%99%85%E8%A6%86%E7%9B%96%E7%94%A8%E6%88%B7-2500%20%E4%B8%87%2B-orange\"></a>\n\n<a href=\"https://www.zhihu.com/org/finchat\"><img src=\"https://img.shields.io/badge/FinClip--lightgrey?logo=zhihu&style=social\"></a>\n<a href=\"https://www.finclip.com/blog/\"><img src=\"https://img.shields.io/badge/FinClip%20Blog--lightgrey?logo=ghost&style=social\"></a>\n\n\n\n</div>\n\n<p align=\"center\">\n\n<div align=\"center\">\n\n[官方网站](https://www.finclip.com/) | [示例小程序](https://www.finclip.com/#/market) | [开发文档](https://www.finclip.com/mop/document/) | [部署指南](https://www.finclip.com/mop/document/introduce/quickStart/cloud-server-deployment-guide.html) | [SDK 集成指南](https://www.finclip.com/mop/document/introduce/quickStart/intergration-guide.html) | [API 列表](https://www.finclip.com/mop/document/develop/api/overview.html) | [组件列表](https://www.finclip.com/mop/document/develop/component/overview.html) | [隐私承诺](https://www.finclip.com/mop/document/operate/safety.html)\n\n</div>\n\n-----\n## 🤔 FinClip 是什么?\n\n有没有**想过**，开发好的微信小程序能放在自己的 APP 里直接运行，只需要开发一次小程序，就能在不同的应用中打开它，是不是很不可思议？\n\n有没有**试过**，在自己的 APP 中引入一个 SDK ，应用中不仅可以打开小程序，还能自定义小程序接口，修改小程序样式，是不是觉得更不可思议？\n\n这就是 FinClip ，就是有这么多不可思议！\n\n## ⚙️ 操作步骤\n### 第一步 配置 build.gradle 文件\n在工程的 `build.gradle` 中添加 maven 仓库的地址：\n```bash\nbuildscript {\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath \"com.android.tools.build:gradle:3.5.2\"\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.60\"\n    }\n}\nallprojects {\n    repositories {\n        google()\n        jcenter()\n        maven { url \"https://jitpack.io\" }\n        maven {\n            url \"https://gradle.finogeeks.club/repository/applet/\"\n            credentials {\n                username \"applet\"\n                password \"123321\"\n            }\n        }\n    }\n}\n```\n### 第二步 在 gradle 中依赖 SDK\n`implementation 'com.finogeeks.lib:finapplet:+'`\n\n### 第三步 配置混淆规则\n集成 SDK 之后，为了避免 SDK 中部分不能被混淆的代码被混淆，需要在工程的混淆规则配置文件中增加以下配置：\n\n``-keep class com.finogeeks.** {*;}``\n\n### 第四步 SDK初始化\n我们强烈建议在 `Application` 中对SDK进行初始化，初始化 SDK 需要传入的各项参数如下：\n```java\nFinAppConfig config = new FinAppConfig.Builder()\n        .setAppKey(\"SDKKEY\")\n\t      .setAppSecret(\"SECRET\")\n        .setApiUrl(\"https://api.finclip.com\")\n        .setApiPrefix(\"/api/v1/mop/\")\n        .setGlideWithJWT(false)\n        .build();\nFinCallback<Object> callback = new FinCallback<Object>() {\n    @Override\n    public void onSuccess(Object result) {\n        // SDK初始化成功\n    }\n\n    @Override\n    public void onError(int code, String error) {\n        // SDK初始化失败\n        Toast.makeText(AppletApplication.this, \"SDK初始化失败\", Toast.LENGTH_SHORT).show();\n    }\n\n    @Override\n    public void onProgress(int status, String error) {\n\n    }\n};\nFinAppClient.INSTANCE.init(this, config, callback);\n```\n SDK 采用多进程机制实现，每个小程序运行在独立的进程中，即一个小程序对应一个进程。在初始化SDK时，要特别注意的一点是：**小程序进程在创建的时候,不需要执行任何初始化操作，即使是小程序SDK的初始化，也不需要在小程序进程中执行。**\n\n> 举个例子🌰<br>\n    应用使用了一些第三方库，这些库需要在应用启动时先初始化，那么在 Application 中执行初始化时，只有当前进程为宿主进程时才需要初始化这些第三方库，小程序进程是不需要初始化这些库的。<br>\n    因此，在初始化SDK之前，一定要判断当前进程是哪一个进程，如果是小程序进程，就不进行任何操作了：\n\n```java\nif (FinAppClient.INSTANCE.isFinAppProcess(this)) {\n    return;\n}\n```\n\n### 第五步 打开小程序\n```java\nFinAppClient.INSTANCE.getAppletApiManager().startApplet(this, \"appid\");\n```\n\n\n- **SDK KEY** 和 **SDK SECRET** 可以从 [FinClip](https://finclip.com/#/home)  获取，点 [这里](https://finclip.com/#/register) 注册账号；\n- 进入平台后，在「应用管理」页面添加你自己的包名后，点击「复制」即可获得  key\\secret\\apisever 字段；\n- **apiServer** 和 **apiPrefix** 是固定字段，请直接参考本 DEMO ；\n- **小程序 ID** 是管理后台上架的小程序 APP ID，需要在「小程序管理」中创建并在「应用管理」中关联；\n> 小程序 ID 与 微信小程序ID 不一样哦！（这里是特指 FinClip 平台的 ID ）\n\n\n## 📋 集成文档\n[点击这里](https://www.finclip.com/mop/document/introduce/quickStart/intergration-guide.html#_2-android-%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90) 查看 Android 快速集成文档\n\n## 📘 目录结构\n\n```\n.\n├─.github\n│          \n├─.idea 由IDE自动生成，无需关注\n│          \n├─app 项目源码主目录\n│  │  \n│  │  build.gradle 应用构建配置\n│  │  \n│  │  proguard-rules.pro 混淆配置\n│  │  \n│  ├─release 构建应用生成的apk目录\n│  │      \n│  └─src\n│      ├─androidTest 单元测试目录，由IDE自动生成，无需关注\n│      │                          \n│      ├─main 应用源码主目录\n│      │  │  AndroidManifest.xml 应用清单文件\n│      │  │  \n│      │  ├─java 应用源码目录\n│      │  │                              \n│      │  └─res 资源文件目录\n│      │      ├─drawable darwable资源目录\n│      │      │      \n│      │      ├─drawable-v24 darwable资源目录\n│      │      │      \n│      │      ├─layout 布局文件目录\n│      │      │      \n│      │      ├─mipmap-anydpi-v26 图片资源目录\n│      │      │      \n│      │      ├─mipmap-hdpi 图片资源目录\n│      │      │      \n│      │      ├─mipmap-mdpi 图片资源目录\n│      │      │      \n│      │      ├─mipmap-xhdpi 图片资源目录\n│      │      │      \n│      │      ├─mipmap-xxhdpi 图片资源目录\n│      │      │      \n│      │      ├─mipmap-xxxhdpi 图片资源目录\n│      │      │      \n│      │      └─values 各项资源值配置目录\n│      │              \n│      └─test 单元测试目录，由IDE自动生成，无需关注\n│                                  \n└─gradle gradle版本配置目录，一般情况下无需关注\n```\n\n## 🔗 常用链接\n以下内容是您在 FinClip 进行开发与体验时，常见的问题与指引信息\n\n- [FinClip 官网](https://www.finclip.com/#/home)\n- [示例小程序](https://www.finclip.com/#/market)\n- [文档中心](https://www.finclip.com/mop/document/)\n- [SDK 部署指南](https://www.finclip.com/mop/document/introduce/quickStart/intergration-guide.html)\n- [小程序代码结构](https://www.finclip.com/mop/document/develop/guide/structure.html)\n- [iOS 集成指引](https://www.finclip.com/mop/document/runtime-sdk/ios/ios-integrate.html)\n- [Android 集成指引](https://www.finclip.com/mop/document/runtime-sdk/android/android-integrate.html)\n- [Flutter 集成指引](https://www.finclip.com/mop/document/runtime-sdk/flutter/flutter-integrate.html)\n\n## ☎️ 联系我们\n微信扫描下面二维码，关注官方公众号 **「凡泰极客」**，获取更多精彩内容。<br>\n<img width=\"150px\" src=\"https://www.finclip.com/mop/document/images/ic_qr.svg\">\n\n微信扫描下面二维码，加入官方微信交流群，获取更多精彩内容。<br>\n<img width=\"150px\" src=\"https://www-cdn.finclip.com/images/qrcode/qrcode_shequn_text.png\">\n\n## Stargazers\n[![Stargazers repo roster for @finogeeks/finclip-android-demo](https://reporoster.com/stars/finogeeks/finclip-android-demo)](https://github.com/finogeeks/finclip-android-demo/stargazers)\n\n## Forkers\n[![Forkers repo roster for @finogeeks/finclip-android-demo](https://reporoster.com/forks/finogeeks/finclip-android-demo)](https://github.com/finogeeks/finclip-android-demo/network/members)\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "content": "apply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-android-extensions'\napply plugin: 'kotlin-kapt'\n\nandroid {\n    compileSdkVersion 29\n    buildToolsVersion \"29.0.2\"\n    defaultConfig {\n        applicationId \"com.finogeeks.finclip.demo\"\n        minSdkVersion 19\n        targetSdkVersion 29\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n\n        multiDexEnabled true\n\n        buildConfigField \"String\", \"APP_KEY\", \"\\\"22LyZEib0gLTQdU3MUauATBwgfnTCJjdr7FCnywmAEM=\\\"\"\n        // App Secret\n        buildConfigField \"String\", \"APP_SECRET\", \"\\\"bdfd76cae24d4313\\\"\"\n        // API服务地址\n        buildConfigField \"String\", \"API_URL\", \"\\\"https://api.finclip.com\\\"\"\n        // API服务前缀\n        buildConfigField \"String\", \"API_PREFIX\", \"\\\"/api/v1/mop/\\\"\"\n\n        ndk {\n            abiFilters \"x86\", \"armeabi\", 'armeabi-v7a', 'arm64-v8a'\n        }\n    }\n    signingConfigs {\n        debug {\n            keyAlias \"FinClipDemo\"\n            keyPassword \"fino123456\"\n            storeFile file(\"../finclip.jks\")\n            storePassword \"fino123456\"\n        }\n        release {\n            keyAlias \"FinClipDemo\"\n            keyPassword \"fino123456\"\n            storeFile file(\"../finclip.jks\")\n            storePassword \"fino123456\"\n        }\n    }\n    buildTypes {\n        debug {\n            minifyEnabled false\n            signingConfig signingConfigs.debug\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n        release {\n            minifyEnabled true\n            signingConfig signingConfigs.release\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    packagingOptions {\n        // libsdkcore.so是被加固过的，不能被压缩，否则加载动态库时会报错\n        doNotStrip \"*/x86/libsdkcore.so\"\n        doNotStrip \"*/x86_64/libsdkcore.so\"\n        doNotStrip \"*/armeabi/libsdkcore.so\"\n        doNotStrip \"*/armeabi-v7a/libsdkcore.so\"\n        doNotStrip \"*/arm64-v8a/libsdkcore.so\"\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    implementation 'androidx.appcompat:appcompat:1.2.0'\n    implementation 'androidx.constraintlayout:constraintlayout:2.0.0'\n    implementation 'com.google.android.material:material:1.2.0'\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.2.0'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'\n    implementation 'com.finogeeks.lib:finapplet:2.49.11'\n    implementation 'cn.bingoogolapple:bga-qrcode-zbar:1.3.7'\n\n}"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\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\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n\n-keep class com.finogeeks.** {*;}"
  },
  {
    "path": "app/src/androidTest/java/com/finogeeks/mop/demo/ExampleInstrumentedTest.java",
    "content": "package com.finogeeks.mop.demo;\n\nimport android.content.Context;\n\nimport androidx.test.platform.app.InstrumentationRegistry;\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n\n        assertEquals(\"com.finogeeks.mop.demo\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.finogeeks.mop.demo\">\n\n    <uses-permission android:name=\"android.permission.VIBRATE\" />\n    <application\n        android:name=\".MopApplication\"\n        android:allowBackup=\"false\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\">\n\n        <activity\n            android:name=\".MainActivity\"\n            android:label=\"@string/app_name\"\n            android:theme=\"@style/AppTheme.NoActionBar\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n        <activity\n            android:name=\".InputContentActivity\"\n            android:label=\"@string/app_name\"\n            android:theme=\"@style/AppTheme.NoActionBar\" />\n\n        <activity\n            android:name=\".ScanStartAppletActivity\"\n            android:theme=\"@style/Theme.AppCompat.Light.NoActionBar\"\n            android:label=\"@string/scan_start_applet\" />\n        <activity\n            android:name=\".ScanQRCodeActivity\"\n            android:theme=\"@style/Theme.AppCompat.Light.NoActionBar\"\n            android:configChanges=\"keyboardHidden|orientation|screenSize\"\n            android:label=\"@string/scan_start_applet\"\n            android:screenOrientation=\"portrait\" />\n    </application>\n</manifest>"
  },
  {
    "path": "app/src/main/java/com/finogeeks/mop/demo/AppletHandler.java",
    "content": "package com.finogeeks.mop.demo;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.os.Bundle;\nimport android.widget.Toast;\n\nimport androidx.annotation.NonNull;\n\nimport com.finogeeks.lib.applet.page.view.moremenu.MoreMenuItem;\nimport com.finogeeks.lib.applet.page.view.moremenu.MoreMenuType;\nimport com.finogeeks.lib.applet.rest.model.GrayAppletVersionConfig;\nimport com.finogeeks.lib.applet.sdk.api.IAppletHandler;\n\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * {@link IAppletHandler}实现类，用于实现一些业务场景，例如注册\"更多\"菜单项，转发小程序等。\n */\npublic class AppletHandler implements IAppletHandler {\n\n    @NonNull\n    private Context mContext;\n\n    private AppletHandler() {\n    }\n\n    public AppletHandler(@NonNull Context context) {\n        this.mContext = context;\n    }\n\n    /**\n     * 获取灰度发布配置参数\n     *\n     * @param appId 小程序ID\n     * @return 灰度发布配置参数\n     */\n    @Nullable\n    @Override\n    public List<GrayAppletVersionConfig> getGrayAppletVersionConfigs(@NotNull String appId) {\n        return null;\n    }\n\n    /**\n     * 获取注册的\"更多\"菜单项\n     *\n     * @param appId 小程序ID\n     * @return 注册的\"更多\"菜单项\n     */\n    @Nullable\n    @Override\n    public List<MoreMenuItem> getRegisteredMoreMenuItems(@NotNull String appId) {\n        List<MoreMenuItem> items = new ArrayList<>();\n        MoreMenuItem item0 = new MoreMenuItem(\"WXShareAPPFriends\", \"微信好朋友\", MoreMenuType.ON_MINI_PROGRAM);\n        items.add(item0);\n        MoreMenuItem item1 = new MoreMenuItem(\"WXShareAPPMoments\", \"微信朋友圈\", MoreMenuType.ON_MINI_PROGRAM, true);\n        items.add(item1);\n        MoreMenuItem item2 = new MoreMenuItem(\"ShareSinaWeibo\", \"新浪微博\", MoreMenuType.ON_MINI_PROGRAM);\n        items.add(item2);\n        MoreMenuItem item3 = new MoreMenuItem(\"ShareQQFirends\", \"QQ\", MoreMenuType.ON_MINI_PROGRAM);\n        items.add(item3);\n        MoreMenuItem item4 = new MoreMenuItem(\"ShareDingDing\", \"Dingding\", MoreMenuType.ON_MINI_PROGRAM);\n        items.add(item4);\n        MoreMenuItem item5 = new MoreMenuItem(\"ShareLinks\", \"标题以后端配置为准\", MoreMenuType.ON_MINI_PROGRAM);\n        items.add(item5);\n        MoreMenuItem item6 = new MoreMenuItem(\"SharePicture\", \"SharePicture\", MoreMenuType.ON_MINI_PROGRAM);\n        items.add(item6);\n        MoreMenuItem item7 = new MoreMenuItem(\"Restart\", \"Restart\", MoreMenuType.COMMON);\n        items.add(item7);\n        MoreMenuItem item8 = new MoreMenuItem(\"Desktop\", \"Desktop\", MoreMenuType.COMMON);\n        items.add(item8);\n        return items;\n    }\n\n    /**\n     * 获取用户信息\n     *\n     * @return 用户信息[Map]\n     */\n    @Nullable\n    @Override\n    public Map<String, String> getUserInfo() {\n        return null;\n    }\n\n    /**\n     * 小程序导航栏中的\"关闭\"按钮被点击\n     *\n     * @param appId 小程序ID\n     */\n    @Override\n    public void onNavigationBarCloseButtonClicked(@NotNull String appId) {\n        Toast.makeText(mContext, \"点击了小程序 \" + appId + \" 的导航栏关闭按钮\", Toast.LENGTH_SHORT).show();\n    }\n\n    /**\n     * 注册的\"更多\"菜单项被点击\n     *\n     * @param appId      小程序ID\n     * @param path       小程序页面路径\n     * @param menuItemId 被点击的菜单条目的ID\n     * @param appInfo    小程序信息，是一串json，包含了小程序id、小程序名称、小程序图标、用户id、转发的数据内容等信息。\n     *                   [appInfo]的内容格式如下：\n     *                   {\n     *                   \"appTitle\": \"凡泰小程序\",\n     *                   \"appAvatar\": \"https:\\/\\/www.finogeeks.club\\/statics\\/images\\/swan_mini\\/swan_logo.png\",\n     *                   \"appId\": \"5df36b3f687c5c00013e9fd1\",\n     *                   \"userId\": \"finogeeks\",\n     *                   \"params\": {\n     *                   \"title\": \"apt-test-tweet-接口测试发布的动态！@#￥%……&*（\",\n     *                   \"desc\": \"您身边的服务专家\",\n     *                   \"imageUrl\": \"finfile:\\/\\/tmp_fc15edd8-2ff6-4c54-9ee9-fe5ee034033d1576550313667.png\",\n     *                   \"path\": \"pages\\/tweet\\/tweet-detail.html?fcid=%40staff_staff1%3A000000.finogeeks.com&timelineId=db0c2098-031e-41c4-b9c6-87a5bbcf681d&shareId=3dfa2f78-19fc-42fc-b3a9-4779a6dac654\",\n     *                   \"appInfo\": {\n     *                   \"weixin\": {\n     *                   \"path\": \"\\/studio\\/pages\\/tweet\\/tweet-detail\",\n     *                   \"query\": {\n     *                   \"fcid\": \"@staff_staff1:000000.finogeeks.com\",\n     *                   \"timelineId\": \"db0c2098-031e-41c4-b9c6-87a5bbcf681d\"\n     *                   }\n     *                   }\n     *                   }\n     *                   }\n     *                   }\n     * @param bitmap     小程序封面图片。如果[appInfo].params.imageUrl字段为http、https的链接地址，那么小程序封面图片\n     *                   就取[appInfo].params.imageUrl对应的图片，否则小程序的封面图片取[bitmap]。\n     * @param callback   转发小程序结果回调。\n     */\n    @Override\n    public void onRegisteredMoreMenuItemClicked(@NotNull String appId, @NotNull String path, @NotNull String menuItemId, @Nullable String appInfo, @Nullable Bitmap bitmap, @NotNull IAppletCallback callback) {\n        Toast.makeText(mContext, \"小程序\" + appId + \"的\" + path + \"页面的菜单\" + menuItemId + \"被点击了，appInfo : \" + appInfo + \" bitmap : \" + bitmap, Toast.LENGTH_SHORT).show();\n        callback.onSuccess(null);\n    }\n\n    /**\n     * 转发小程序\n     *\n     * @param appInfo  小程序信息，是一串json，包含了小程序id、小程序名称、小程序图标、用户id、转发的数据内容等信息。\n     *                 [appInfo]的内容格式如下：\n     *                 {\n     *                 \"appTitle\": \"凡泰小程序\",\n     *                 \"appAvatar\": \"https:\\/\\/www.finogeeks.club\\/statics\\/images\\/swan_mini\\/swan_logo.png\",\n     *                 \"appId\": \"5df36b3f687c5c00013e9fd1\",\n     *                 \"userId\": \"finogeeks\",\n     *                 \"params\": {\n     *                 \"title\": \"apt-test-tweet-接口测试发布的动态！@#￥%……&*（\",\n     *                 \"desc\": \"您身边的服务专家\",\n     *                 \"imageUrl\": \"finfile:\\/\\/tmp_fc15edd8-2ff6-4c54-9ee9-fe5ee034033d1576550313667.png\",\n     *                 \"path\": \"pages\\/tweet\\/tweet-detail.html?fcid=%40staff_staff1%3A000000.finogeeks.com&timelineId=db0c2098-031e-41c4-b9c6-87a5bbcf681d&shareId=3dfa2f78-19fc-42fc-b3a9-4779a6dac654\",\n     *                 \"appInfo\": {\n     *                 \"weixin\": {\n     *                 \"path\": \"\\/studio\\/pages\\/tweet\\/tweet-detail\",\n     *                 \"query\": {\n     *                 \"fcid\": \"@staff_staff1:000000.finogeeks.com\",\n     *                 \"timelineId\": \"db0c2098-031e-41c4-b9c6-87a5bbcf681d\"\n     *                 }\n     *                 }\n     *                 }\n     *                 }\n     *                 }\n     * @param bitmap   小程序封面图片。如果[appInfo].params.imageUrl字段为http、https的链接地址，那么小程序封面图片\n     *                 就取[appInfo].params.imageUrl对应的图片，否则小程序的封面图片取[bitmap]。\n     * @param callback 转发小程序结果回调。\n     */\n    @Override\n    public void shareAppMessage(@NotNull String appInfo, @Nullable Bitmap bitmap, @NotNull IAppletCallback callback) {\n        Toast.makeText(mContext, \"点击了转发按钮，去实现您的转发/分享逻辑吧\", Toast.LENGTH_SHORT).show();\n    }\n\n    @Override\n    public void chooseAvatar(@NonNull IAppletCallback iAppletCallback) {\n\n    }\n\n    @Override\n    public boolean contact(@NonNull JSONObject jsonObject) {\n        return false;\n    }\n\n    @Override\n    public boolean feedback(@NonNull Bundle bundle) {\n        return false;\n    }\n\n    @Override\n    public void getJSSDKConfig(@NonNull JSONObject jsonObject, @NonNull IAppletCallback iAppletCallback) {\n\n    }\n\n    @Override\n    public void getPhoneNumber(@NonNull IAppletCallback iAppletCallback) {\n\n    }\n\n    @androidx.annotation.Nullable\n    @Override\n    public Map<String, String> getWebViewCookie(@NonNull String s) {\n        return null;\n    }\n\n    @Override\n    public boolean launchApp(@androidx.annotation.Nullable String s) {\n        return false;\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/finogeeks/mop/demo/InputContentActivity.java",
    "content": "package com.finogeeks.mop.demo;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.EditText;\nimport android.widget.Toast;\n\nimport androidx.annotation.Nullable;\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.appcompat.widget.Toolbar;\n\n/**\n * 输入内容页面\n */\npublic class InputContentActivity extends AppCompatActivity {\n\n    public static final String EXTRA_NAME_INPUT_CONTENT = \"input_content\";\n\n    @Override\n    protected void onCreate(@Nullable Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_input_content);\n        Toolbar toolbar = findViewById(R.id.toolbar);\n        setSupportActionBar(toolbar);\n        final EditText editTextInputContent = findViewById(R.id.edt_input_content);\n        Button btnConfirm = findViewById(R.id.btn_confirm);\n        btnConfirm.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                if (editTextInputContent.length() < 1) {\n                    Toast.makeText(InputContentActivity.this, getString(R.string.fin_clip_input_content_hint), Toast.LENGTH_SHORT).show();\n                    return;\n                }\n                Intent intent = new Intent();\n                intent.putExtra(EXTRA_NAME_INPUT_CONTENT, editTextInputContent.getText().toString());\n                setResult(RESULT_OK, intent);\n                finish();\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/finogeeks/mop/demo/MainActivity.java",
    "content": "package com.finogeeks.mop.demo;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.View;\nimport android.widget.Button;\n\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.appcompat.widget.Toolbar;\n\nimport com.finogeeks.lib.applet.client.FinAppClient;\nimport com.finogeeks.lib.applet.sdk.api.request.IFinAppletRequest;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class MainActivity extends AppCompatActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n        Toolbar toolbar = findViewById(R.id.toolbar);\n        setSupportActionBar(toolbar);\n\n        Button btnScan = findViewById(R.id.btn_scan);\n        btnScan.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                startActivity(new Intent(MainActivity.this, ScanStartAppletActivity.class));\n            }\n        });\n\n\n        Button btnCharts = findViewById(R.id.btn_charts);\n        btnCharts.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                FinAppClient.INSTANCE.getAppletApiManager().startApplet(MainActivity.this, IFinAppletRequest.Companion.fromAppId(\"5facb3a52dcbff00017469bd\"),null);\n            }\n        });\n\n        Button btnDemo = findViewById(R.id.btn_demo);\n        btnDemo.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                FinAppClient.INSTANCE.getAppletApiManager().startApplet(MainActivity.this,IFinAppletRequest.Companion.fromAppId( \"5fa214a29a6a7900019b5cc1\"),null);\n            }\n        });\n\n        Button btnProfile = findViewById(R.id.btn_profile);\n        btnProfile.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                FinAppClient.INSTANCE.getAppletApiManager().startApplet(MainActivity.this, IFinAppletRequest.Companion.fromAppId(\"5fa215459a6a7900019b5cc3\"),null);\n            }\n        });\n\n        Button btnCustomApi = findViewById(R.id.btn_custom_api);\n        btnCustomApi.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                Map<String, String> params = new HashMap<>();\n                params.put(\"path\", \"pages/index/index\");\n                FinAppClient.INSTANCE.getAppletApiManager().startApplet(MainActivity.this, IFinAppletRequest.Companion.fromAppId(\"5fc8934aefb8c600019e9747\").setStartParams(params),null);\n            }\n        });\n\n        Button btnH5Api = findViewById(R.id.btn_h5_api);\n        btnH5Api.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                Map<String, String> params = new HashMap<>();\n                params.put(\"path\", \"pages/webview/webview\");\n                FinAppClient.INSTANCE.getAppletApiManager().startApplet(MainActivity.this, \"5fc8934aefb8c600019e9747\", params,null);\n            }\n        });\n\n        Button btnAppletLogin = findViewById(R.id.btn_applet_login);\n        btnAppletLogin.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                FinAppClient.INSTANCE.getAppletApiManager().startApplet(MainActivity.this, \"60f051ea525ea10001c0bd22\",null);\n            }\n        });\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/finogeeks/mop/demo/MopApplication.java",
    "content": "package com.finogeeks.mop.demo;\n\nimport android.app.Activity;\nimport android.graphics.Color;\nimport android.widget.Toast;\n\nimport androidx.multidex.MultiDexApplication;\n\nimport com.finogeeks.lib.applet.client.FinAppClient;\nimport com.finogeeks.lib.applet.client.FinAppConfig;\nimport com.finogeeks.lib.applet.client.FinAppProcessClient;\nimport com.finogeeks.lib.applet.interfaces.FinCallback;\nimport com.finogeeks.lib.applet.interfaces.IApi;\nimport com.finogeeks.lib.applet.sdk.api.IAppletApiManager;\nimport com.finogeeks.mop.demo.customapi.CustomApi;\nimport com.finogeeks.mop.demo.customapi.CustomH5Api;\nimport com.finogeeks.mop.demo.customapi.user.LoginApi;\nimport com.finogeeks.mop.demo.customapi.user.ProfileApi;\n\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class MopApplication extends MultiDexApplication {\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n\n        if (FinAppClient.INSTANCE.isFinAppProcess(this)) {\n            // 小程序进程\n            // 小程序进程中注册api的方法能获取到小程序所在activity对象，可以用做创建对话框的context参数）\n            FinAppProcessClient.INSTANCE.setCallback(new FinAppProcessClient.Callback() {\n                @Override\n                public List<IApi> getRegisterExtensionApis(@NotNull Activity activity) {\n                    ArrayList<IApi> apis = new ArrayList<>();\n                    apis.add(new LoginApi(activity));\n                    apis.add(new ProfileApi());\n                    return apis;\n                }\n\n                @Nullable\n                @Override\n                public List<IApi> getRegisterExtensionWebApis(@NotNull Activity activity) {\n                    return null;\n                }\n            });\n            return;\n        }\n\n        FinAppConfig.UIConfig uiConfig = new FinAppConfig.UIConfig();\n        uiConfig.setHideNavigationBarCloseButton(true);\n        uiConfig.setHideBackHome(true);\n        uiConfig.setHideForwardMenu(true);\n        uiConfig.setHideFeedbackAndComplaints(true);\n        uiConfig.setMoreMenuStyle(FinAppConfig.UIConfig.MORE_MENU_DEFAULT);\n\n        FinAppConfig.UIConfig.CapsuleConfig capsuleConfig = new FinAppConfig.UIConfig.CapsuleConfig();\n        capsuleConfig.capsuleWidth = 86f;\n        capsuleConfig.capsuleHeight = 31f;\n        capsuleConfig.capsuleRightMargin = 15f;\n        capsuleConfig.capsuleCornerRadius = 15.5f;\n        capsuleConfig.capsuleBorderWidth = 0.5f;\n        capsuleConfig.capsuleBgLightColor = Color.BLACK;\n        capsuleConfig.capsuleBgDarkColor = Color.WHITE;\n        capsuleConfig.capsuleBorderLightColor = Color.parseColor(\"#88ffffff\");\n        capsuleConfig.capsuleBorderDarkColor = Color.parseColor(\"#a5a9b4\");\n\n        capsuleConfig.moreLightImage = R.mipmap.more_light;\n        capsuleConfig.moreDarkImage = R.mipmap.more_dark;\n        capsuleConfig.moreBtnWidth = 25f;\n        capsuleConfig.moreBtnLeftMargin = 11f;\n\n        capsuleConfig.closeLightImage = R.mipmap.close_light;\n        capsuleConfig.closeDarkImage = R.mipmap.close_dark;\n        capsuleConfig.closeBtnWidth = 25f;\n        capsuleConfig.closeBtnLeftMargin = 9f;\n\n        capsuleConfig.capsuleDividerLightColor = Color.parseColor(\"#88ffffff\");\n        capsuleConfig.capsuleDividerDarkColor = Color.parseColor(\"#a5a9b4\");\n\n        uiConfig.setCapsuleConfig(capsuleConfig);\n\n        FinAppConfig config = new FinAppConfig.Builder()\n                .setSdkKey(BuildConfig.APP_KEY)\n                .setSdkSecret(BuildConfig.APP_SECRET)\n                .setApiUrl(BuildConfig.API_URL)\n                .setApiPrefix(BuildConfig.API_PREFIX)\n                .setDebugMode(BuildConfig.DEBUG)\n                .setUiConfig(uiConfig)\n                .setEncryptionType(FinAppConfig.ENCRYPTION_TYPE_SM)\n                .build();\n\n        FinAppClient.INSTANCE.init(this, config, new FinCallback<Object>() {\n            @Override\n            public void onSuccess(Object result) {\n                Toast.makeText(MopApplication.this, \"SDK初始化成功\", Toast.LENGTH_SHORT).show();\n                // 注册自定义小程序API\n                FinAppClient.INSTANCE.getExtensionApiManager().registerApi(new CustomApi(MopApplication.this));\n                // 注册自定义H5 API\n                FinAppClient.INSTANCE.getExtensionWebApiManager().registerApi(new CustomH5Api(MopApplication.this));\n                // 设置IAppletHandler实现类\n                FinAppClient.INSTANCE.setAppletHandler(new AppletHandler(getApplicationContext()));\n\n                // 在主进程设置\"小程序进程调用主进程\"的处理方法\n                // 开发者也可以选择在主进程其他合适的代码位置设置处理方法\n                FinAppClient.INSTANCE.getAppletApiManager()\n                        .setAppletProcessCallHandler(new IAppletApiManager.AppletProcessCallHandler() {\n                            @Override\n                            public void onAppletProcessCall(@NotNull String name,\n                                                            @Nullable String params,\n                                                            @Nullable FinCallback<String> callback) {\n                                if (callback != null) {\n                                    if (name.equals(LoginApi.API_NAME_LOGIN)) {\n                                        // 从主进程获取登录信息，返回给小程序进程\n                                        // 这里返回的是虚拟的用户登录信息，开发者请从APP里面自行获取用户登录信息\n                                        JSONObject jsonObject = new JSONObject();\n                                        try {\n                                            jsonObject.put(\"userId\", \"123\");\n                                        } catch (JSONException e) {\n                                            e.printStackTrace();\n                                        }\n                                        callback.onSuccess(jsonObject.toString());\n                                    }\n                                }\n                            }\n                        });\n            }\n\n            @Override\n            public void onError(int code, String error) {\n                Toast.makeText(MopApplication.this, \"SDK初始化失败\", Toast.LENGTH_SHORT).show();\n            }\n\n            @Override\n            public void onProgress(int status, String error) {\n\n            }\n        });\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/finogeeks/mop/demo/ScanQRCodeActivity.kt",
    "content": "package com.finogeeks.mop.demo\n\nimport android.Manifest\nimport android.app.Activity\nimport android.content.Intent\nimport android.os.Build\nimport android.os.Bundle\nimport android.os.VibrationEffect\nimport android.os.Vibrator\nimport android.util.Log\nimport android.view.MenuItem\nimport android.view.View\nimport android.widget.Toast\nimport androidx.appcompat.app.AppCompatActivity\nimport cn.bingoogolapple.qrcode.core.QRCodeView\nimport com.finogeeks.lib.applet.modules.permission.checkPermissions\nimport kotlinx.android.synthetic.main.activity_scan_qr_code.*\n\n/**\n * 扫描二维码页面\n */\nclass ScanQRCodeActivity : AppCompatActivity(), QRCodeView.Delegate {\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_scan_qr_code)\n        setSupportActionBar(toolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n    }\n\n    override fun onStart() {\n        super.onStart()\n        checkPermissions(Manifest.permission.CAMERA, granted = {\n            zBarView.visibility = View.VISIBLE\n            zBarView.setDelegate(this)\n            zBarView.startCamera()\n            zBarView.startSpotAndShowRect()\n        })\n    }\n\n    override fun onStop() {\n        zBarView.stopCamera()\n        super.onStop()\n    }\n\n    override fun onDestroy() {\n        zBarView.onDestroy()\n        super.onDestroy()\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        zBarView.showScanRect()\n    }\n\n    override fun onScanQRCodeSuccess(result: String?) {\n        vibrate()\n        zBarView.startSpot()\n        setResult(Activity.RESULT_OK, Intent().putExtra(EXTRA_RESULT, result))\n        finish()\n    }\n\n    override fun onCameraAmbientBrightnessChanged(isDark: Boolean) {\n        var tipText: String = zBarView.scanBoxView.tipText\n        val ambientBrightnessTip = \"\\n环境过暗，请打开闪光灯\"\n        if (isDark) {\n            if (!tipText.contains(ambientBrightnessTip)) {\n                zBarView.scanBoxView.tipText = tipText + ambientBrightnessTip\n            }\n        } else {\n            if (tipText.contains(ambientBrightnessTip)) {\n                tipText = tipText.substring(0, tipText.indexOf(ambientBrightnessTip))\n                zBarView.scanBoxView.tipText = tipText\n            }\n        }\n    }\n\n    override fun onScanQRCodeOpenCameraError() {\n        Toast.makeText(this, \"打开相机出错\", Toast.LENGTH_SHORT).show()\n    }\n\n    private fun vibrate() {\n        val vibrator = getSystemService(VIBRATOR_SERVICE) as Vibrator\n        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {\n            @Suppress(\"DEPRECATION\")\n            vibrator.vibrate(200)\n        } else {\n            try {\n                val effect = VibrationEffect.createOneShot(\n                    200,\n                    VibrationEffect.DEFAULT_AMPLITUDE\n                )\n                vibrator.vibrate(effect, null)\n            } catch (iae: IllegalArgumentException) {\n                Log.e(TAG, \"Failed to create VibrationEffect\", iae)\n            }\n        }\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        if (item.itemId == android.R.id.home) {\n            onBackPressed()\n            return true\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    companion object {\n\n        private const val TAG = \"ScanQRCodeActivity\"\n\n        const val EXTRA_RESULT = \"result\"\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/finogeeks/mop/demo/ScanStartAppletActivity.kt",
    "content": "package com.finogeeks.mop.demo\n\nimport android.annotation.SuppressLint\nimport android.app.Activity\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.MenuItem\nimport android.widget.Toast\nimport androidx.appcompat.app.AppCompatActivity\nimport com.finogeeks.lib.applet.client.FinAppClient\nimport com.finogeeks.lib.applet.interfaces.FinCallback\nimport com.finogeeks.lib.applet.sdk.api.request.IFinAppletRequest\nimport kotlinx.android.synthetic.main.activity_scan_start_applet.*\n\n/**\n * 扫码启动小程序的页面\n */\n@SuppressLint(\"Registered\")\nopen class ScanStartAppletActivity : AppCompatActivity() {\n\n    private var isStartingApplet = false\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_scan_start_applet)\n        setSupportActionBar(toolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n\n        btnScan.setOnClickListener { scanQRCode() }\n    }\n\n    private fun scanQRCode() {\n        startActivityForResult(Intent(this, ScanQRCodeActivity::class.java), REQ_CODE_SCAN_QR_CODE)\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        if (requestCode == REQ_CODE_SCAN_QR_CODE) {\n            if (resultCode == Activity.RESULT_OK && data != null) {\n                if (!isStartingApplet)\n                    FinAppClient.appletApiManager.startApplet(this, IFinAppletRequest.fromQrCode(data.getStringExtra(ScanQRCodeActivity.EXTRA_RESULT)),\n                        object : FinCallback<String?> {\n                            override fun onSuccess(result: String?) {\n                                isStartingApplet = false\n                                runOnUiThread {\n                                    Toast.makeText(this@ScanStartAppletActivity, \"扫码成功\", Toast.LENGTH_SHORT).show()\n                                }\n                            }\n\n                            override fun onError(code: Int, error: String?) {\n                                isStartingApplet = false\n                                runOnUiThread {\n                                    Toast.makeText(this@ScanStartAppletActivity, error, Toast.LENGTH_SHORT).show()\n                                }\n                            }\n\n                            override fun onProgress(status: Int, info: String?) {\n                            }\n                        })\n                    /*FinAppClient.appletApiManager.startAppletByQrcode(this, data.getStringExtra(ScanQRCodeActivity.EXTRA_RESULT),\n                            object : FinCallback<String> {\n                                override fun onSuccess(result: String?) {\n                                    isStartingApplet = false\n                                    runOnUiThread {\n                                        Toast.makeText(this@ScanStartAppletActivity, \"扫码成功\", Toast.LENGTH_SHORT).show()\n                                    }\n                                }\n\n                                override fun onError(code: Int, error: String?) {\n                                    isStartingApplet = false\n                                    runOnUiThread {\n                                        Toast.makeText(this@ScanStartAppletActivity, error, Toast.LENGTH_SHORT).show()\n                                    }\n                                }\n\n                                override fun onProgress(status: Int, info: String?) {\n                                }\n                            })*/\n            }\n        }\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        if (item.itemId == android.R.id.home) {\n            onBackPressed()\n            return true\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    companion object {\n\n        private const val TAG = \"StartAppletActivity\"\n\n        private const val REQ_CODE_SCAN_QR_CODE = 0x01\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/finogeeks/mop/demo/customapi/CustomApi.java",
    "content": "package com.finogeeks.mop.demo.customapi;\n\nimport android.content.Context;\nimport android.content.Intent;\n\nimport androidx.annotation.NonNull;\n\nimport com.finogeeks.lib.applet.api.AbsApi;\nimport com.finogeeks.lib.applet.interfaces.ICallback;\nimport com.finogeeks.mop.demo.InputContentActivity;\nimport com.finogeeks.mop.demo.R;\n\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport static android.app.Activity.RESULT_OK;\nimport static com.finogeeks.mop.demo.InputContentActivity.EXTRA_NAME_INPUT_CONTENT;\n\n/**\n * 自定义小程序API\n * 跳转到原生APP的输入内容页面{@link InputContentActivity}，输入内容提交后，把输入的内容回传给小程序\n */\npublic class CustomApi extends AbsApi {\n\n    private static final int REQ_CODE_INPUT_CONTENT = 0x01;\n\n    private static final String API_NAME_ON_NATIVE = \"onNative\";\n\n    @NonNull\n    private Context mContext;\n\n    public CustomApi(@NonNull Context context) {\n        mContext = context;\n    }\n\n    /**\n     * @return 支持可调用的api名称的数组\n     */\n    @Override\n    public String[] apis() {\n        return new String[]{API_NAME_ON_NATIVE};\n    }\n\n    /**\n     * 接收到对应的api调用时，会调用此方法，在此方法中处理api调用的功能逻辑\n     *\n     * @param event    事件名称，即api名称\n     * @param param    参数\n     * @param callback 回调接口\n     */\n    @Override\n    public void invoke(String event, JSONObject param, ICallback callback) {\n        if (API_NAME_ON_NATIVE.equals(event)) {\n            Intent intent = new Intent(mContext, InputContentActivity.class);\n            callback.startActivityForResult(intent, REQ_CODE_INPUT_CONTENT);\n        }\n    }\n\n    @Override\n    public void onActivityResult(int requestCode, int resultCode, Intent data, ICallback callback) {\n        super.onActivityResult(requestCode, resultCode, data, callback);\n        if (requestCode == REQ_CODE_INPUT_CONTENT) {\n            if (resultCode == RESULT_OK && data != null) {\n                String inputContent = data.getStringExtra(EXTRA_NAME_INPUT_CONTENT);\n                JSONObject jsonObject = new JSONObject();\n                try {\n                    jsonObject.put(\"text\", inputContent);\n                    callback.onSuccess(jsonObject);\n                } catch (JSONException e) {\n                    e.printStackTrace();\n                    callback.onFail();\n                }\n            } else {\n                JSONObject jsonObject = new JSONObject();\n                try {\n                    jsonObject.put(\"errMsg\", mContext.getString(R.string.fin_clip_get_input_content_failed));\n                    callback.onFail(jsonObject);\n                } catch (JSONException e) {\n                    e.printStackTrace();\n                    callback.onFail();\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/finogeeks/mop/demo/customapi/CustomH5Api.java",
    "content": "package com.finogeeks.mop.demo.customapi;\n\nimport android.content.Context;\nimport android.content.Intent;\n\nimport androidx.annotation.NonNull;\n\nimport com.finogeeks.lib.applet.api.AbsApi;\nimport com.finogeeks.lib.applet.interfaces.ICallback;\nimport com.finogeeks.mop.demo.InputContentActivity;\nimport com.finogeeks.mop.demo.R;\n\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport static android.app.Activity.RESULT_OK;\nimport static com.finogeeks.mop.demo.InputContentActivity.EXTRA_NAME_INPUT_CONTENT;\n\n/**\n * 自定义H5 API\n * 跳转到原生APP的输入内容页面{@link InputContentActivity}，输入内容提交后，把输入的内容回传给小程序中的网页\n */\npublic class CustomH5Api extends AbsApi {\n\n    private static final int REQ_CODE_INPUT_CONTENT = 0x02;\n\n    private static final String API_NAME_USER_DEFINE_NATIVE = \"user_define_native\";\n\n    @NonNull\n    private Context mContext;\n\n    public CustomH5Api(@NonNull Context context) {\n        mContext = context;\n    }\n\n    /**\n     * @return 支持可调用的api名称的数组\n     */\n    @Override\n    public String[] apis() {\n        return new String[]{API_NAME_USER_DEFINE_NATIVE};\n    }\n\n    /**\n     * 接收到对应的api调用时，会调用此方法，在此方法中处理api调用的功能逻辑\n     *\n     * @param event    事件名称，即api名称\n     * @param param    参数\n     * @param callback 回调接口\n     */\n    @Override\n    public void invoke(String event, JSONObject param, ICallback callback) {\n        if (API_NAME_USER_DEFINE_NATIVE.equals(event)) {\n            Intent intent = new Intent(mContext, InputContentActivity.class);\n            callback.startActivityForResult(intent, REQ_CODE_INPUT_CONTENT);\n        }\n    }\n\n    @Override\n    public void onActivityResult(int requestCode, int resultCode, Intent data, ICallback callback) {\n        super.onActivityResult(requestCode, resultCode, data, callback);\n        if (requestCode == REQ_CODE_INPUT_CONTENT) {\n            if (resultCode == RESULT_OK && data != null) {\n                String inputContent = data.getStringExtra(EXTRA_NAME_INPUT_CONTENT);\n                JSONObject jsonObject = new JSONObject();\n                try {\n                    jsonObject.put(\"text\", inputContent);\n                    callback.onSuccess(jsonObject);\n                } catch (JSONException e) {\n                    e.printStackTrace();\n                    callback.onFail();\n                }\n            } else {\n                JSONObject jsonObject = new JSONObject();\n                try {\n                    jsonObject.put(\"errMsg\", mContext.getString(R.string.fin_clip_get_input_content_failed));\n                    callback.onFail(jsonObject);\n                } catch (JSONException e) {\n                    e.printStackTrace();\n                    callback.onFail();\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/finogeeks/mop/demo/customapi/user/LoginApi.java",
    "content": "package com.finogeeks.mop.demo.customapi.user;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.content.DialogInterface;\n\nimport com.finogeeks.lib.applet.api.AbsApi;\nimport com.finogeeks.lib.applet.client.FinAppProcessClient;\nimport com.finogeeks.lib.applet.interfaces.FinCallback;\nimport com.finogeeks.lib.applet.interfaces.ICallback;\n\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\npublic class LoginApi extends AbsApi {\n\n    public final static String API_NAME_LOGIN = \"login\"; // 小程序基础库调用的api名称\n    private final Activity activity;\n\n    public LoginApi(Activity activity) {\n        this.activity = activity;\n    }\n\n    @Override\n    public String[] apis() {\n        return new String[]{API_NAME_LOGIN};\n    }\n\n    @Override\n    public void invoke(String event, JSONObject param, ICallback callback) {\n        if (event.equals(API_NAME_LOGIN)) {\n            showAuthDialog(callback);\n        }\n    }\n\n    /**\n     * 显示获取用户登录信息的授权提示对话框\n     */\n    private void showAuthDialog(final ICallback callback) {\n        // 是否需要显示授权提示对话框请开发者按照产品需求自行处理\n        new AlertDialog.Builder(activity)\n                .setTitle(\"是否同意授权获取用户登录信息？\")\n                .setNegativeButton(\"拒绝\", new DialogInterface.OnClickListener() {\n                    @Override\n                    public void onClick(DialogInterface dialog, int which) {\n                        callback.onFail();\n                    }\n                })\n                .setPositiveButton(\"同意\", new DialogInterface.OnClickListener() {\n                    @Override\n                    public void onClick(DialogInterface dialog, int which) {\n                        loginMainProcess(callback);\n                    }\n                })\n                .show();\n    }\n\n    /**\n     * 从主进程获取用户登录信息\n     */\n    private void loginMainProcess(final ICallback callback) {\n        // 小程序进程调用主进程，在主进程获取用户信息后返回给小程序进程\n        FinAppProcessClient.INSTANCE.getAppletProcessApiManager()\n                .callInMainProcess(API_NAME_LOGIN, null, new FinCallback<String>() {\n                    @Override\n                    public void onSuccess(final String result) {\n                        // 需要在主线程调用callback方法\n                        activity.runOnUiThread(new Runnable() {\n                            @Override\n                            public void run() {\n                                try {\n                                    callback.onSuccess(new JSONObject(result));\n                                } catch (JSONException e) {\n                                    e.printStackTrace();\n                                    callback.onFail();\n                                }\n                            }\n                        });\n                    }\n\n                    @Override\n                    public void onError(int code, String error) {\n                        callback.onFail();\n                    }\n\n                    @Override\n                    public void onProgress(int status, String info) {\n                    }\n                });\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/finogeeks/mop/demo/customapi/user/ProfileApi.java",
    "content": "package com.finogeeks.mop.demo.customapi.user;\n\nimport com.finogeeks.lib.applet.api.AbsApi;\nimport com.finogeeks.lib.applet.interfaces.ICallback;\n\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\npublic class ProfileApi extends AbsApi {\n\n    private final static String API_NAME_GET_USER_PROFILE = \"getUserProfile\"; // 小程序基础库调用的api名称\n\n    @Override\n    public String[] apis() {\n        return new String[]{API_NAME_GET_USER_PROFILE};\n    }\n\n    @Override\n    public void invoke(String event, JSONObject param, ICallback callback) {\n        if (event.equals(API_NAME_GET_USER_PROFILE)) {\n            JSONObject jsonObject = new JSONObject();\n            try {\n                // 这里返回的是虚拟的用户个人信息，开发者请从APP里面自行获取用户个人信息\n                jsonObject.put(\"nickName\", \"张三\");\n            } catch (JSONException e) {\n                e.printStackTrace();\n            }\n            callback.onSuccess(jsonObject);\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path\n        android:fillColor=\"#008577\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        android:pathData=\"M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#00000000\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#00000000\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_input_content.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <androidx.appcompat.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_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:titleTextColor=\"@android:color/white\" />\n\n    <EditText\n        android:id=\"@+id/edt_input_content\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"10dp\"\n        android:layout_marginEnd=\"10dp\"\n        android:hint=\"@string/fin_clip_input_content_hint\"\n        app:layout_constraintBottom_toTopOf=\"@+id/btn_confirm\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n    <Button\n        android:id=\"@+id/btn_confirm\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"10dp\"\n        android:layout_marginEnd=\"10dp\"\n        android:text=\"@string/fin_clip_confirm\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/edt_input_content\" />\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout 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=\".MainActivity\"\n    tools:showIn=\"@layout/activity_main\">\n\n    <androidx.appcompat.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_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:titleTextColor=\"@android:color/white\" />\n\n    <Button\n        android:id=\"@+id/btn_scan\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"@string/scan_start_applet\"\n        app:layout_constraintBottom_toTopOf=\"@+id/btn_demo\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintVertical_chainStyle=\"packed\" />\n\n    <Button\n        android:id=\"@+id/btn_charts\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"@string/fin_clip_charts_applet\"\n        app:layout_constraintBottom_toTopOf=\"@+id/btn_demo\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintVertical_chainStyle=\"packed\" />\n\n    <Button\n        android:id=\"@+id/btn_demo\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"20dp\"\n        android:text=\"@string/fin_clip_demo_applet\"\n        app:layout_constraintBottom_toTopOf=\"@+id/btn_profile\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/btn_charts\" />\n\n    <Button\n        android:id=\"@+id/btn_profile\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"20dp\"\n        android:text=\"@string/fin_clip_profile_applet\"\n        app:layout_constraintBottom_toTopOf=\"@+id/btn_custom_api\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/btn_demo\" />\n\n    <Button\n        android:id=\"@+id/btn_custom_api\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"20dp\"\n        android:text=\"@string/fin_clip_custom_api\"\n        app:layout_constraintBottom_toTopOf=\"@+id/btn_h5_api\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/btn_profile\" />\n\n    <Button\n        android:id=\"@+id/btn_h5_api\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"20dp\"\n        android:text=\"@string/fin_clip_custom_h5_api\"\n        app:layout_constraintBottom_toTopOf=\"@+id/btn_applet_login\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/btn_custom_api\" />\n\n    <Button\n        android:id=\"@+id/btn_applet_login\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"20dp\"\n        android:text=\"@string/fin_clip_applet_login\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/btn_h5_api\" />\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_scan_qr_code.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout 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\n    <androidx.appcompat.widget.Toolbar\n        android:id=\"@+id/toolbar\"\n        style=\"@style/Widget.AppCompat.Toolbar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"?attr/actionBarSize\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n    <cn.bingoogolapple.qrcode.zbar.ZBarView\n        android:id=\"@+id/zBarView\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:visibility=\"gone\"\n        app:layout_constraintTop_toBottomOf=\"@id/toolbar\"\n        app:qrcv_animTime=\"1000\"\n        app:qrcv_barCodeTipText=\"将条码放入框内，即可自动扫描\"\n        app:qrcv_barcodeRectHeight=\"120dp\"\n        app:qrcv_borderColor=\"@android:color/white\"\n        app:qrcv_borderSize=\"1px\"\n        app:qrcv_cornerColor=\"@color/colorPrimaryDark\"\n        app:qrcv_cornerLength=\"20dp\"\n        app:qrcv_cornerSize=\"3dp\"\n        app:qrcv_isAutoZoom=\"true\"\n        app:qrcv_isBarcode=\"false\"\n        app:qrcv_isOnlyDecodeScanBoxArea=\"true\"\n        app:qrcv_isShowDefaultGridScanLineDrawable=\"false\"\n        app:qrcv_isShowDefaultScanLineDrawable=\"true\"\n        app:qrcv_isShowLocationPoint=\"true\"\n        app:qrcv_isShowTipBackground=\"false\"\n        app:qrcv_isShowTipTextAsSingleLine=\"false\"\n        app:qrcv_isTipTextBelowRect=\"true\"\n        app:qrcv_maskColor=\"#4D000000\"\n        app:qrcv_qrCodeTipText=\"将二维码放入框内，即可自动扫描\"\n        app:qrcv_rectWidth=\"260dp\"\n        app:qrcv_scanLineColor=\"@color/colorPrimaryDark\"\n        app:qrcv_tipTextMargin=\"20dp\"\n        app:qrcv_tipTextSize=\"12sp\"\n        app:qrcv_toolbarHeight=\"@dimen/fin_applet_navbar_height\"\n        app:qrcv_topOffset=\"80dp\"\n        app:qrcv_verticalBias=\"-1\"\n        tools:visibility=\"visible\" />\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_scan_start_applet.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"#f5f5f6\">\n\n    <androidx.appcompat.widget.Toolbar\n        android:id=\"@+id/toolbar\"\n        style=\"@style/Widget.AppCompat.Toolbar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"?attr/actionBarSize\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n    <Button\n        android:id=\"@+id/btnScan\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"10dp\"\n        android:layout_marginTop=\"40dp\"\n        android:layout_marginEnd=\"10dp\"\n        android:text=\"扫码打开小程序\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon 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>"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon 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>"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#008577</color>\n    <color name=\"colorPrimaryDark\">#00574B</color>\n    <color name=\"colorAccent\">#D81B60</color>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <dimen name=\"fab_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">FinClip Demo</string>\n    <string name=\"fin_clip_charts_applet\">绘图小程序</string>\n    <string name=\"fin_clip_demo_applet\">官方小程序</string>\n    <string name=\"fin_clip_profile_applet\">智能对账单</string>\n    <string name=\"fin_clip_custom_api\">自定义小程序API示例</string>\n    <string name=\"fin_clip_custom_h5_api\">自定义H5 API示例</string>\n    <string name=\"fin_clip_applet_login\">小程序登录授权示例</string>\n    <string name=\"fin_clip_input_content_hint\">请输入内容</string>\n    <string name=\"fin_clip_confirm\">确定</string>\n    <string name=\"fin_clip_get_input_content_failed\">获取输入内容失败</string>\n    <string name=\"scan_start_applet\">扫码打开小程序</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\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    <style name=\"AppTheme.NoActionBar\">\n        <item name=\"windowActionBar\">false</item>\n        <item name=\"windowNoTitle\">true</item>\n    </style>\n\n    <style name=\"AppTheme.AppBarOverlay\" parent=\"ThemeOverlay.AppCompat.Dark.ActionBar\" />\n\n    <style name=\"AppTheme.PopupOverlay\" parent=\"ThemeOverlay.AppCompat.Light\" />\n\n</resources>\n"
  },
  {
    "path": "app/src/test/java/com/finogeeks/mop/demo/ExampleUnitTest.java",
    "content": "package com.finogeeks.mop.demo;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.5.0'\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61\"\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n\n        maven {\n            url \"https://gradle.finogeeks.club/repository/applet/\"\n            credentials {\n                username \"applet\"\n                password \"123321\"\n            }\n        }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Fri Feb 07 17:25:22 CST 2020\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-5.4.1-all.zip\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\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# AndroidX package structure to make it clearer which packages are bundled with the\n# Android operating system, and which are packaged with your app's APK\n# https://developer.android.com/topic/libraries/support-library/androidx-rn\nandroid.useAndroidX=true\n# Automatically convert third-party libraries to use AndroidX\nandroid.enableJetifier=true\n\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\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\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\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\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\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\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\" -a \"$nonstop\" = \"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# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\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\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\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\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 Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_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\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'\nrootProject.name='mopdemo'\n"
  }
]